Kul*_*shi 8 python oop inheritance multiple-inheritance method-resolution-order
超级方法如何在python中实际运行?
在给定的代码中:
class A(object):
def test(self):
return 'A'
class B(A):
def test(self):
return 'B->'+super(B, self).test()
class C(A):
def test(self):
return 'C'
class D(B,C):
pass
print B().test() # B->A
print D().test() # B->C ????
# MRO of classes are as
print 'mro of A', A.__mro__ # [A,object]
print 'mro of B', B.__mro__ # [B,A,object]
print 'mro of C', C.__mro__ # [C,A,object]
print 'mro of D', D.__mro__ # [D,B,C,A,object]
Run Code Online (Sandbox Code Playgroud)
当test在D上调用时,它输出B->C而不是B->A(我期待的).
B中的超级内容如何引用C的实例?
在常见情况下, super() 采用两个参数:一个类和该类的实例。(1) 实例对象(自身)决定将使用哪个MRO来解析任何属性。(2) 提供的类确定该 MRO 的子集,因为 super() 仅使用 MRO 中出现在提供的类之后的那些条目。
因此,在上述情况下,当从 D 对象的实例调用 B 内部的 super 时,self 引用 D 对象(即实例对象),并且 D(即实例对象)的 mro 是 [D,B,C,A],因此根据 (2 )仅使用 MRO 中 B 之后出现的那些条目。即[C,A]
因此,推荐的用法是提供使用 super() 作为第一个参数、标准 self 作为第二个参数的类。生成的对象将保留 self 的实例命名空间字典,但它仅检索在 MRO 中晚于提供的类找到的类上定义的属性。
因此,如果我们将 B 重新定义为
class B(A):
def test(self):
return 'B->'+super(C, self).test()
Run Code Online (Sandbox Code Playgroud)
然后调用 D().test() 将输出 ==> 'B->A' 解释: from (1) 上述 MRO of self == [D,B,C,A,object] from (2) 以上仅那些将使用在提供的类(即 C)之后发生的 MRO 条目,因此 super 将调用 A 的测试方法。