请向我解释以下内容。如果我执行这个:
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 Order或 MRO。根据称为 C3 linearisation 的系统,Python 类继承层次结构是线性化的,给出了特定的顺序。 .
super()
使用该顺序查找该顺序中的 next 属性(包括方法)。给定一个当前实例和一个类,它将搜索 过去 给定类的属性的顺序。对于这两个 Child*
类,MRO 首先列出 Child*
类,然后是 Base1
和 Base2
。在你的最后一个例子中,你告诉 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/