繁体   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