python - 使用 super() 访问第二个基类的方法

标签 python class oop python-3.x inheritance

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

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()才能得到第二个基类的方法呢?

最佳答案

你正在处理 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() 也可以在外部 方法中使用;然后,当您为搜索选择不同的起点时,您可以轻松地看到会发生什么:

>>> 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'

关于python - 使用 super() 访问第二个基类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35315615/

相关文章:

python - 转换字符串日期,不能用零填充

javascript - 'that' 传递时与 'this' 不一样,为什么?

c++ - 类名宏

c++ - 将函数实现为自由函数而不是 C++ 中的成员有什么优势吗?

c# - 构造函数重载和类参数

python - 使用枚举作为类中的标志,Python

java - 数据库中存在缓慢问题的 Java 对象列表

python - 如何知道数组和字典等python对象的字节大小? - 简单的方法

python - 有没有办法同时执行多个函数,但是从列表中执行?

python - 带有 youtube dl 的不和谐机器人音乐不会卡在网页下载中