【问题标题】:MRO with multiple inheritance in python在python中具有多重继承的MRO
【发布时间】:2013-01-04 22:19:31
【问题描述】:

Python webpage 的文档中,python 中经典类的方法解析顺序被描述为深度优先的从左到右搜索。我试图用这段代码对此进行测试:

class A(object):
def __init__(self):
    print "Initialized A"

class B(A):
    def test():
        print "Initialized B"

class C(A):
    def __init__(self):
        print "Initialized C"

class D(B, C):
    def __init__(self):
        super(D, self).__init__()
        print "Initialized D"

当我创建对象 D 的实例时:

D()

我得到了结果:

Initialized C
Initialized D

虽然我期望打印“Initialized A”、“Initialized D”,因为 MRO 是深度优先的,但初始化首先在 B 中搜索,当未找到时(就是这种情况),它应该在层次结构中更深,并且在 B 的基类(即 A)中查找函数。有人能解释一下为什么我得到 C 的 init 函数而不是 A 的那个吗?

【问题讨论】:

    标签: python multiple-inheritance method-resolution-order


    【解决方案1】:

    D 的 MRO 是:

    print(D.mro())
    [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]
    

    所以

    super(D, self).__init__()
    

    D 之后的self.__class__.mro() 的第一个类中查找__init__ 方法。由于B 没有__init__,因此它会在C 中查找__init__ 方法。它找到C.__init__,因此

    super(D, self).__init__()
    

    致电C.__init__(self)

    请注意,super 并未尝试访问 getattr(B, __init__)。相反,它在B.__dict__ 中寻找'__init__'

    【讨论】:

      【解决方案2】:

      您的类继承自object,因此不是经典类。这是一门新式的课。 (任何继承自新式类的类也是新式类。)

      请注意,super 无论如何都不能与经典类一起使用。您引用的“深度优先从左到右”规则只是当您尝试访问未在实例上直接定义的属性时搜索顺序基类的属性查找规则。经典类不提供这样的 MRO --- 如果不显式引用特定的超类,就无法访​​问属性的“超类值”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-01
        • 2021-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-02
        相关资源
        最近更新 更多