【问题标题】:Simple python inheritance简单的python继承
【发布时间】:2023-03-22 16:55:01
【问题描述】:
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
  1. 为什么我的猫tom = Cat() 没有nlegs 属性?
  2. 我们应该在Cat.__init__ 中显式调用Animal.__init__(),还是应该做一些更花哨的事情,比如使用super
  3. 如果我想创建一个有 5 条腿的猫,我需要在 Cat.__init__ 接口中添加额外的参数吗?

【问题讨论】:

    标签: python inheritance constructor


    【解决方案1】:

    要建立在其他人所说的基础上,是的,您需要调用父级的 __init__ 方法。

    通常最好使用 super.但是,在某些情况下(特别是当您从多个类继承时),这可能是一个很大的问题。我将避免详细介绍,various articles which discuss it 不缺。 (此外,其他一些“特殊”功能也有一些奇怪之处。例如,您可以使用super(SomeCls, self).__getitem__(5),但super(SomeCls, self)[5] 将不起作用。)

    作为一个为什么使用它是个好主意的简单示例,您可以使 DogCat 继承自 Mammal(继承自 Animal),而不必更改其他代码中的位置比DogCat 继承自哪个类。

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

    还请记住,并非所有内容都需要在初始化时进行设置。对于这个例子,不要在__init__ 方法中设置像nlegs 这样的东西更有意义。相反,只需直接在类中设置即可。例如

    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 函数),而在初始化时设置的属性将不可用。

    【讨论】:

    • 谢谢!那么为什么在这个例子中直接在类中设置更有意义呢?你能澄清一下什么时候在初始化时设置属性更好,什么时候在类定义上更好?
    • @wim - 我添加了一些编辑来澄清一些事情。简而言之,如果它会随着每个实例而改变,那么在 __init__ 构造函数中设置。否则,让__init__函数更简单,直接在类定义中设置。希望有帮助!
    • 我不认为每只动物都有 4 条腿(有些没有)。所以,它不应该是 Animal 类的一部分。
    • @JBernardo - 没错,好点!我把它变成了哺乳动物类。除了鲸鱼等特殊情况(它们仍然有腿,它们刚刚变成退化的内骨),大多数(未受伤/突变的)哺乳动物有 4 条肢体,所以它更适合。
    【解决方案2】:

    使用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
    

    【讨论】:

    • 是的。派生类使用父类__init__ 方法,如果它没有定义一个。你不需要对object做任何事情。
    【解决方案3】:

    您需要查看有关 super() 的 Python 文档。例如,您通常会通过调用 super(Cat, self).__init__(<any args>) 来开始(或结束)您的 Cat.__init__() 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-30
      • 2011-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多