代码之家  ›  专栏  ›  技术社区  ›  varnie

在Python中混合超级调用和经典调用

  •  9
  • varnie  · 技术社区  · 15 年前

    首先,让我引用“专家Python编程”一书中的一篇文章:

    让B班被叫来两次!

    class A(object):
        def __init__(self):
            print "A"
            super(A, self).__init__()
    
    class B(object):
        def __init__(self):
            print "B"
            super(B, self).__init__()
    
    class C(A,B):
        def __init__(self):
            print "C"
            A.__init__(self)
            B.__init__(self)
    
    print "MRO:", [x.__name__ for x in C.__mro__]  #prints MRO: ['C', 'A', 'B', 'object']
    C()  #prints C A B B
    

    最后,这里解释一下这里发生了什么:

    从而使super(A,self).\uu init\uu()调用B的构造函数。 super应该用于整个类层次结构。问题是有时候 此层次结构的一部分位于第三方代码中。

    super(A, self).__init__() 调用B的构造函数”。请解释一下这个时刻。谢谢。

    2 回复  |  直到 15 年前
        1
  •  4
  •   Manoj Govindan    15 年前

    的文档 super 他说:

    返回一个代理对象,该对象将方法调用委托给类型为的父类或同级类。这对于访问已在类中重写的继承方法非常有用。搜索顺序与getattr()使用的顺序相同,只是跳过了类型本身。

    A.__init__(self) 从内部 C 这个 super(A, self) 会回来的 <super: <class 'A'>, <C object>> . 正如实例所示 C级 ( <C object> )C继承层次结构中的所有类都会被提取。以及 __init__

    若要验证这一点,请添加另一个类“Z”,并让“C”也从“Z”继承。看看会发生什么。

    class Z(object):
        def __init__(self):
            print "Z"
            super(Z, self).__init__()
    
    class C(A, B, Z):    
        def __init__(self):
            print "C"
            A.__init__(self)
            B.__init__(self)
            Z.__init__(self)
    

    A B Z . B类 将呼叫 也。

        2
  •  10
  •   stephan    15 年前

    要理解这种行为,你必须理解 super 不调用基类,而是沿着 __mro__ . 所以,电话 super(A, self).__init__() 看看那个 __mro__ == ['C', 'A', 'B', 'object'] ,看到 B 作为下一个具有匹配方法的类并调用 B类 .

    C

    class C(A,B):
        def __init__(self):
            print "C1"
            A.__init__(self)
            print "C2"
            B.__init__(self)
            print "C3"
    

    你得到了吗

    MRO: ['C', 'A', 'B', 'object']
    C1
    A
    B
    C2
    B
    C3
    

    它显示了 A 电话 B类