[英]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
正試圖做個體動物所做的事情並控制一群動物。
將它分成兩種不同的對象可能更好:一種動物,以及某種AnimalGroup
如Zoo
或Farm
或Herd
。 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.