简体   繁体   English

为子类和父类中的属性赋值的区别

[英]Difference between assigning values to attributes in child class and parent class

Choice A: 选择A:

class Mammal(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return str(self.name)

class Human(Mammal):
    def __init__(self, name):
        self.name = name

me = Human("John")
print(me)

Choice B: 选择B:

class Mammal(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return str(self.name)

class Human(Mammal):
    def __init__(self, name):
        super(Human, self).__init__(name)


me = Human("John")
print(me)

Both choices return the same result, but can someone please explain what's the difference between assigning the name to child class (Human) and the parent class (Mammal)? 两种选择都会返回相同的结果,但有人可以解释一下将名称分配给子类(Human)和父类(Mammal)之间的区别吗? Is there a better one between these two choices? 这两个选择之间有更好的选择吗?

Thank you very much! 非常感谢你!

This is really a question of class design and maintenance. 这实际上是课堂设计和维护的问题。 Obviously in this case there are no characteristics that Humans have that Mammals don't and no other Mammals. 显然,在这种情况下,人类没有哺乳动物没有的特征,也没有其他哺乳动物。 But, for instance, let's say you later update Mammal to have a "feet" attribute: 但是,比方说,让我们说你以后更新Mammal有一个“脚”属性:

class Mammal(object):
    def __init__(self, name, feet):
        self.name = name
        self.feet = feet

Mammals now have a number of feet, and so you might expect Humans to also. 哺乳动物现在有很多脚,所以你可能也会期待人类。 But me.feet will throw an error, because the Human __init__ didn't initialize it, and the Mammal __init__ didn't run. me.feet会抛出错误,因为Human __init__没有初始化它,而且Mammal __init__没有运行。 Nor can you declare feet with me = Human('Joe', 2) , because the Human __init__ doesn't take that argument. 你也不能用我声明脚me = Human('Joe', 2) ,因为人__init__没有接受那个论点。 So you've created a maintenance problem -- Humans are now not really good Mammals, because some of their promised attributes are always undefined. 所以你已经创造了一个维护问题 - 人类现在不是很好的哺乳动物,因为它们的一些承诺属性总是未定义的。

Using super avoids this problem: 使用super避免了这个问题:

class Human(Mammal):
    def __init__(self, name):
        super(Human, self).__init__(name, 2)

Of course, this requires you to subclass Human if you want a lot of pirates, but that's another problem. 当然,如果你想要很多盗版者,这需要你继承Human,但这是另一个问题。

The converse situation might be if you decided that most Mammals don't have names. 相反的情况可能是你决定大多数哺乳动物都没有名字。 Obviously, in this case, you would want to define name only in the Human __init__ . 显然,在这种情况下,您只想在Human __init__定义名称。

In the first example, you only say that Human inherits from Mammal ( the .__init__ on Mammal is not called), and if you try to use self.name you'll get an attribute error. 在第一个示例中,您只说人类继承自哺乳动物(Mammal上的.__init__未被调用),如果您尝试使用self.name您将获得属性错误。

In the second example you are, in Human class, using the self.name from Mammal. 在第二个例子中,在Human类中,您使用来自Mammal的self.name

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM