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

时间:2013-08-08 23:31:23

标签: python python-2.7 superclass

选择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)

选择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)

两种选择都会返回相同的结果,但有人可以解释一下将名称分配给子类(Human)和父类(Mammal)之间的区别吗?这两种选择之间有更好的选择吗?

非常感谢!

2 个答案:

答案 0 :(得分:2)

这实际上是课堂设计和维护的问题。显然,在这种情况下,人类没有哺乳动物没有的特征,也没有其他哺乳动物。但是,例如,假设您稍后更新Mammal以具有“脚”属性:

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

哺乳动物现在有很多脚,所以你可能也会想到人类。但是me.feet会抛出错误,因为人类__init__没有初始化它,而哺乳动物__init__也没有运行。你也不能用me = Human('Joe', 2)声明脚,因为人类__init__不接受这个论点。所以你已经创造了一个维护问题 - 人类现在不是很好的哺乳动物,因为它们的一些承诺属性总是未定义的。

使用super避免了这个问题:

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

当然,如果你想要很多盗版者,这需要你继承Human,但这是另一个问题。

如果您认为大多数哺乳动物没有名字,那么情况可能相反。显然,在这种情况下,您只想在人类__init__中定义名称。

答案 1 :(得分:0)

在第一个示例中,您只说人类继承自哺乳动物(Mammal上的.__init__未被调用),如果您尝试使用self.name,则会收到属性错误。< / p>

在第二个示例中,您在Human课程中使用来自Mammal的self.name