简单的python继承

wim*_*wim 11 python inheritance constructor

class Animal(object):
    def __init__(self, nlegs=4):
        print '__init__ Animal'
        self.nlegs = nlegs

class Cat(Animal):
    def __init__(self, talk='meow'):
        print '__init__ Cat'
        self.talk = talk

class Dog(Animal):
    def __init__(self, talk='woof'):
        print '__init__ Dog'
        self.talk = talk
Run Code Online (Sandbox Code Playgroud)
  1. 为什么我的猫tom = Cat()没有nlegs属性?
  2. 我们应该明确地Animal.__init__()从内部打电话Cat.__init__,还是应该做一些更加花哨的事情,比方说呢super
  3. 如果我想创建一个有5条腿的猫,我需要在Cat.__init__界面中添加其他参数吗?

Joe*_*ton 12

要建立在其他人所说的基础之上,是的,你需要调用父__init__方法.

通常最好使用super.但是,在某些情况下(特别是当你从多个类继承时)它可能是一个很大的问题.我会避免详细介绍,不乏讨论它各种文章.(此外,其他一些"特殊"功能也存在一些奇怪之处.例如,你可以做super(SomeCls, self).__getitem__(5)super(SomeCls, self)[5]不会工作.)

作为一个简单的例子,为什么使用它是一个好主意,你可以创建DogCat继承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
Run Code Online (Sandbox Code Playgroud)

基本上,如果某些内容可能会在实例之间发生变化(例如猫的颜色)或者需要在初始化时完成(例如打开文件),那么可能应该将其设置为__init__.

否则,如果我们想要对类的任何实例都相同,则可以更直接地在类定义中设置它.

此外,以这种方式设置的属性将可用于文档工具(例如内置help函数),而初始化时设置的属性将不可用.