在书里Python 简述(第二版)有一个例子使用
旧式类演示如何以经典解析顺序解析方法,以及
与新订单有何不同?
我通过以新样式重写示例来尝试相同的示例,但结果与旧样式类获得的结果没有什么不同。我用来运行示例的 python 版本是2.5.2.下面是示例:
class Base1(object):
def amethod(self): print "Base1"
class Base2(Base1):
pass
class Base3(object):
def amethod(self): print "Base3"
class Derived(Base2,Base3):
pass
instance = Derived()
instance.amethod()
print Derived.__mro__
电话instance.amethod()
prints Base1
,但根据我对新风格类 MRO 的理解,输出应该是Base3
。电话Derived.__mro__
印刷:
(<class '__main__.Derived'>, <class '__main__.Base2'>, <class '__main__.Base1'>, <class '__main__.Base3'>, <type 'object'>)
我不确定我对新样式类的 MRO 的理解是否不正确,或者我犯了一个我无法检测到的愚蠢错误。请帮助我更好地理解 MRO。
当相同的祖先类在“朴素”的深度优先方法中多次出现时,遗留类与新式类的解析顺序之间的关键区别就出现了——例如,考虑“钻石继承”的情况:
>>> class A: x = 'a'
...
>>> class B(A): pass
...
>>> class C(A): x = 'c'
...
>>> class D(B, C): pass
...
>>> D.x
'a'
在这里,传统风格的解析顺序是 D - B - A - C - A :所以当查找 D.x 时,A 是解析顺序中解决它的第一个基,从而隐藏了 C 中的定义。
>>> class A(object): x = 'a'
...
>>> class B(A): pass
...
>>> class C(A): x = 'c'
...
>>> class D(B, C): pass
...
>>> D.x
'c'
>>>
在这里,新式的顺序是:
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>,
<class '__main__.A'>, <type 'object'>)
with A
被迫按解析顺序仅出现一次并且位于其所有子类之后,以便覆盖(即,C 对成员的覆盖x
)实际上工作很明智。
这是应该避免旧式类的原因之一:具有“类似钻石”模式的多重继承不适用于旧式类,而适用于新式类。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)