简单的Python继承

15 投票
3 回答
6798 浏览
提问于 2025-04-16 19:45
class Animal(object):
    def __init__(self, nlegs=4):
        self.nlegs = nlegs
    
class Cat(Animal):
    def __init__(self, talk='meow'):
        self.talk = talk

class Dog(Animal):
    def __init__(self, talk='woof'):
        self.talk = talk

1. 为什么我的猫 tom = Cat() 没有 nlegs 这个属性?

2. 我们应该在 Cat.__init__ 里面明确调用 Animal.__init__() 吗?还是应该在这里使用 super 呢?

3. 如果我们想要创建一只有5条腿的猫,应该在 Cat.__init__ 的接口中添加额外的参数吗?

相关问题:

3 个回答

2

你需要查看一下Python的文档,关于super()这个函数。举个例子,通常你在写Cat.__init__()这个方法的时候,开头(或者结尾)会调用一下super(Cat, self).__init__(<任何参数>)

4

使用 super

class Cat(Animal):
    def __init__(self, talk='meow', num_legs=4):
        print 'Hay cat'
        self.talk = talk
        super(Cat, self).__init__(num_legs)


tom = Cat()  #tom is a normal cat
bob = Cat('Nyan', 3) #bob is a japanese defective cat
16

接着大家说的内容,没错,你需要调用父类的 __init__ 方法。

一般来说,使用 super 是比较好的选择。不过在某些情况下(特别是当你从多个类继承时),这可能会带来一些麻烦。我就不详细说了,网上有很多关于这个的文章可以参考。还有一些其他“特殊”函数也有些奇怪的地方。例如,你可以用 super(SomeCls, self).__getitem__(5) 来获取值,但 super(SomeCls, self)[5] 就不行。

举个简单的例子,说明为什么使用 super 是个好主意。你可以让 DogCat 继承自 Mammal(而 Mammal 又继承自 Animal),这样在代码中只需要改变 DogCat 继承的类,而不需要其他改动。

至于为什么你的 tom 实例没有 tom.nlegs,是因为你没有调用 Animal__init__ 方法。

另外要记住,并不是所有东西都需要在初始化时设置。对于这个例子,像 nlegs 这样的属性在 __init__ 方法中设置其实没必要。可以直接在类中设置。例如:

class Mammal(object):
    nlimbs = 4
    def __init__(self):
        print "I'm a mammal!"

class Cat(Mammal):
    def __init__(self, color="calico"):
        self.color = color
        super(Cat, self).__init__()
        print "I have {0} legs I am {1}".format(self.nlimbs, self.color)

class FiveLeggedCat(Cat):
    nlimbs = 5

基本上,如果某个属性可能在不同实例之间变化(比如猫的颜色),或者需要在初始化时做(比如打开一个文件),那么它应该在 __init__ 中设置。

否则,如果是我们希望在类的任何实例中都保持一致的属性,直接在类定义中设置会更简洁。

此外,这种方式设置的属性会被文档工具(比如内置的 help 函数)识别,而在初始化时设置的属性则不会。

撰写回答