Python继承和super()

Python继承和super(),python,inheritance,init,super,Python,Inheritance,Init,Super,为什么使用super()调用父类不起作用,而使用“direct”调用效果很好 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__.

为什么使用super()调用父类不起作用,而使用“direct”调用效果很好

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
问题:

  • 这种奇怪的“super()”行为的原因是什么
  • super()能否调用'B'中的init
  • 有没有其他方法可以从父类调用所有的'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'>)
    
    >>>C.\uuu mro__
    (, , )
    
    super(foo,bar)
    提供了对
    type(bar)
    的MRO中
    foo
    之后的下一个类的引用(实际上是代理)
    super(C,self)
    提供了对
    a
    的引用(实际上是一个代理),因此
    a.\uuuu init\uuu
    是结果调用<但是,code>super(A,self)为
    B
    提供了一个代理,导致调用
    B.。\uuuu init\uuuu


    不过,一般的规则是,您确实不知道接下来将调用什么方法,因为您不一定知道
    self
    的类型(它可能是具有不同于
    C
    的MRO的子类的实例)。要正确使用
    super
    ,您需要确保所有潜在的类都在使用它,以便始终正确地调度方法;DR:
    super
    不是访问特定父类的替代品。它的使用必须在所有涉及的类之间进行协调。对于那些不喜欢视频的人,这里是原始的源材料:您可以为每个示例添加
    mro()
    ,我想这可能会有所帮助。