【问题标题】:Access method of second base class with super()使用 super() 访问第二个基类的方法
【发布时间】:2016-05-20 19:54:04
【问题描述】:

请向我解释以下内容。如果我执行这个:

class Base1:
    def foo(self):
        print('in Base1.foo')

b1 = Base1()
b1.foo()


class Base2:
    def foo(self):
        print('in Base2.foo')

b2 = Base2()
b2.foo()

class Child1(Base1, Base2):
    def foo(self):
        super(Child1,self).foo()

c1 =  Child1()
c1.foo()

class Child2(Base1, Base2):
    def foo(self):
        super(Base1,self).foo()

c2 =  Child2()
c2.foo()

我明白了:

in Base1.foo
in Base2.foo
in Base1.foo
in Base2.foo

我理解输出的前三行。但是为什么我要把第一个基类的名字给super(),才能得到第二个基类的方法呢?

【问题讨论】:

    标签: python class oop python-3.x inheritance


    【解决方案1】:

    您正在与Method Resolution OrderMRO 搞混。根据称为C3 linearisation 的系统,Python 类继承层次结构是线性化的,给定特定的顺序。

    super() 使用该顺序在该顺序中查找 next 属性(包括方法)。给定一个当前实例和一个类,它将搜索给定类过去属性的顺序。对于Child* 类,MRO 首先列出Child* 类,然后是Base1Base2。在您的上一个示例中,您告诉super()Base1 之后的下一堂课开始查看该MRO,因此只有Base2.foo() 仍然存在。

    您可以致电class.mro() method,向任何班级询问其 MRO:

    >>> Child2.mro()
    [<class '__main__.Child2'>, <class '__main__.Base1'>, <class '__main__.Base2'>, <class 'object'>]
    

    super() 也可以在outside 方法中使用;然后,您可以轻松地看到当您选择不同的搜索起点时会发生什么:

    >>> super(Child2, Child2()).foo
    <bound method Base1.foo of <__main__.Child2 object at 0x10f40ff98>>
    >>> super(Base1, Child2()).foo
    <bound method Base2.foo of <__main__.Child2 object at 0x10f40ffd0>>
    >>> super(Base2, Child2()).foo
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'super' object has no attribute 'foo'
    

    【讨论】:

    • 我知道方法解析顺序,但我不知道 super() 获得了“下一个”基类...谢谢
    猜你喜欢
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    相关资源
    最近更新 更多