请向我解释以下内容。如果我执行这个:
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()
才能获得第二个基类的方法?
答案 0 :(得分:4)
您正在使用Method Resolution Order或 MRO 。根据一个名为C3 linearisation的系统,Python类继承层次结构是 linearised ,给定一个特定的顺序。
super()
使用该顺序在该排序中查找 next 属性(包括方法)。给定当前实例和类,它将在订单中搜索给定类的属性过去。对于两个Child*
类,MRO首先列出Child*
类,然后是Base1
和Base2
。在上一个示例中,您告诉super()
在Base1
之后从下一课开始查看该MRO,因此只剩下Base2.foo()
。
您可以致电class.mro()
method:
>>> 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'