Python 继承和 super()

标签 python inheritance init super

为什么使用 super() 调用父类不起作用,而使用“直接”调用却可以正常工作?

class A(object):
    def __init__(self, x):
        self.x = x
        print("Inside A __init__. x = %s" % self.x)
class B(object):
    def __init__(self, y):
        self.y = y
        print("Inside B __init__. y = %s" % self.y)
class C(A,B):
    def __init__(self, z):
        super(C, self).__init__(6)
        super(C, self).__init__(5)
        #1.    A.__init__(self,6)
        #2.    B.__init__(self,5)
        self.z = z
        print("Inside C __init__. z = %s" % self.z)
if __name__ == "__main__":
    log = C(2)

使用未注释的“ super ”,我得到的结果是:

Inside A __init__. x = 6
Inside A __init__. x = 5
Inside C __init__. z = 2

因此“B”类init 的代码永远不会被调用。但是在使用注释行“#1”和“#2”之后,代码可以正常工作:

Inside A __init__. x = 6
Inside B __init__. y = 5
Inside C __init__. z = 2

问题:

  1. 这种奇怪的“super()”行为的原因是什么?
  2. super() 可以调用“B”中的init吗?
  3. 还有其他方法可以从父类中调用所有“init”吗?

最佳答案

一个答案,它应该被视为 super 如何工作的示例,而不是如何实际编写代码:

class A(object):
    def __init__(self, x):
        self.x = x
        print("Inside A __init__. x = %s" % self.x)
class B(object):
    def __init__(self, y):
        self.y = y
        print("Inside B __init__. y = %s" % self.y)
class C(A,B):
    def __init__(self, z):
        super(C, self).__init__(6)
        super(A, self).__init__(5)
        self.z = z
        print("Inside C __init__. z = %s" % self.z)
if __name__ == "__main__":
    log = C(2)

每个类都有一个方法解析顺序 (MRO),在查找继承函数时使用。对于C,该顺序是

>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)

super(foo, bar) 提供对 type(bar) 的 MRO 中 foo 之后的下一个类的引用(实际上是代理) super(C, self) 提供对 A 的引用(实际上是代理),因此 A.__init__ 是最终的调用。然而,super(A, self) 提供了 B 的代理,从而导致对 B.__init__ 的调用。

但一般规则是,您确实不知道接下来将调用什么方法,因为您不一定知道 self 的类型(它可能是具有与 C 实例不同的 MRO 的后代类的实例。要正确使用super,您需要确保所有潜在类都在使用它,以便始终正确分派(dispatch)方法。

关于Python 继承和 super(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33638909/

相关文章:

python - Django Admin - 不显示状态表显示 "resolved"的结果

python - 在 Tempo/Jira 中查找所有团队的成员

Python 对象继承

go - init() 函数何时运行?

启动 Linux 上的 Python 脚本

python - 绘制不同多类分类器的精度召回曲线

Python:在封闭范围内赋值之前引用自由变量 'numpy'

java - 使用 Roboguice 和 RxJava 进行继承和依赖注入(inject)

language-agnostic - 更喜欢组合而不是继承?

c++ - 没有复制构造函数的初始化变量