簡體   English   中英

更改多個對象中的屬性

[英]Change attribute in multiple objects

我正在學習Python中的OOP而且我被一件事情搞定了。

我有一個示例類:

class Animal:

    def __init__(self, name="", hunger=0):
        self.name = name
        self.hunger = hunger

    def eat(self):
        self.hunger += 1

還有一些對象:

dog = Animal("dog")
cat = Animal("cat")
giraffe = Animal("giraffe")

我想用方法eat()一次性改變每一個人的飢餓價值。 我已經嘗試過這樣的事情:

Animal.eat()

但它不起作用(存在TypeError,因為缺少參數'self')。

也:

Animal.hunger += 1

不起作用(返回AttributeError)。

如果有人有任何想法,我將非常感激!

您可以維護一個類變量來收集實例並調整eat所有hungers:

class Animal:
    instances = []

    def __init__(self, name="", hunger=0):
        self.name = name
        self.hunger = hunger
        Animal.instances.append(self)

    def eat(self):
        for i in Animal.instances:
            i.hunger += 1

從語義上講,您可能希望將其作為一種classmethod

    @classmethod
    def eat(cls):
        for i in cls.instances:
            i.hunger += 1

如果您願意,您仍然可以在實例上調用它。

你實際上必須像這樣在對象本身上調用它:

cat.eat()
dog.eat()
giraffe.eat()

否則它不知道實際改變哪個對象。 您可以將所有對象存儲在一個數組中並循環遍歷該數組,以便一個接一個地調用所有這些函數:

dog = Animal("dog")
cat = Animal("cat")
giraffe = Animal("giraffe")
animals=[dog, cat, giraffe]
for animalType in animals:
    animalType.eat()

現在,如果你願意,你可以一次完成所有這些操作,也可以一次完成。 但是,您需要在創建它們之后將新動物添加到陣列中以使列表保持最新:

fish=new Animal("fish")
animals.append(fish)
class Animal(object):

    hunger = 0

    def __init__(self, name=""):
        self.name = name


    def eat(self):
        Animal.hunger = Animal.hunger + 1

dog = Animal("dog")
cat = Animal("cat")
giraffe = Animal("giraffe")


dog.eat()

print("Dog's hunger variable is", dog.hunger)
1
dog.eat()

print("Dog's hunger variable is :",dog.hunger)
2

print("Cat's hunger variable is :",cat.hunger)
2

print("Giraffe's hunger variable is :", giraffe.hunger)
2

當在單個實例上調用eat() ,會更新所有實例的hunger變量!

@schwobaseggi對你想做的事情有最直接的答案,但是你想要做的事情似乎是在尋找麻煩。 你有一個課做兩件非常不同的事。 Animal是有一個名字和吃動物, 而且它也使每一種動物實例的軌道,使所有的人吃。 Animal正試圖做個體動物所做的事情並控制一群動物。

將它分成兩種不同的對象可能更好:一種動物,以及某種AnimalGroupZooFarmHerd AnimalGroup類應該負責跟蹤一堆實例並讓它們全部完成。

class AnimalGroup(object):
    def __init__(self, animal_list):
        self.animals = animal_list[:]  

    def add_animal(self, animal):
        self.animals.append(animal)

    def all_eat(self):
        for animal in self.animals:
            animal.eat()

然后

dog = Animal("dog")
cat = Animal("cat")
giraffe = Animal("giraffe")
group = AnimalGroup([dog, cat, giraffe])
group.all_eat()
group.add_animal(Animal("pig"))
group.all_eat()

這將每個類的職責分開,並使以后更容易更改。 您現在可以擁有不同的群體行為,而無需更改動物類別。 您可以擁有從Animal繼承的新動物類,您無需擔心副作用。 例如: class Mammal(Animal) 當我打電話給Mammal.eat ,它會更新所有動物嗎? 它可能。 類變量可能有點棘手。 它應該更新所有動物嗎? 不知道。 使用AnimalGroup對象,您無需擔心。

如果您想要在類上執行某些操作,則必須將其聲明為類變量:

class Animal:
  hunger = 0

  def __init__(self, name=""):
    self.name = name

  @classmethod
  def eat(klass):
    klass.hunger += 1

這樣,只要你調用Animal.eat()你就會引用修改類變量的類方法。 您仍然可以使用self.hunger從Animal類中訪問該變量,但我建議不要這樣,因為它可能會讓人感到困惑,並嘗試確定什么是類變量以及什么是成員變量。

據我所知(我非常喜歡python中的OOP),唯一的方法是創建一個具有該特定屬性的新類

class Animals:
    def __init__(self, animals):
        self.animals = animals
    def all_eat(self):
        for animal in animals:
            animal.eat()

然后你需要做的是:

dog = Animal("dog")
cat = Animal("cat")
giraffe = Animal("giraffe")
animals = Animals((dog, cat, giraffe))
animals.all_eat()

原因是python類本身沒有可調用的屬性,因此您必須分別調用該類的每個實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM