程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

mro顺序是深度优先还是宽度优先?

发布于2019-11-07 20:39     阅读(1396)     评论(0)     点赞(1)     收藏(0)


从Python总结

在类中查找属性名称实质上是通过按从左到右,深度优先的顺序访问祖先类来进行的

然而,

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

D.__mro__列出的类不是按深度优先顺序而是按宽度优先顺序列出。那我误会了吗?谢谢。


解决方案


忽略经典类,Python使用类及其父类C3线性化解析方法和属性查找在复杂的多重继承层次结构中,C3线性化既不是深度优先也不是宽度优先从某种意义上讲,它是:

深度优先,直到遇到要共享父级的类,然后在这些类之间进行广度优先

尽管这是一个非常宽松的特征。

但是,特别是,在不共享父级的简单多个继承层次结构中,它是深度优先的object当然忽略了,它总是共享的)

简单示例–深度优先

>>> class a_0(object): pass
>>> class a_1(object): pass
>>> class b_0(a_0): pass
>>> class b_1(a_1): pass
>>> class c(b_0, b_1): pass

然后

>>> [x.__name__ for x in c.__mro__]
['c', 'b_0', 'a_0', 'b_1', 'a_1', 'object']

共享基础示例-深度然后广度优先

请注意,在您的示例中,您有一个共享的父项(A),该父项导致BC以广度优先的方式遍历。相反,如果您拥有一个更加复杂的层次结构:

>>> class A(object): pass
>>> class B(A): pass
>>> class C(A): pass
>>> class D_0(B, C): pass
>>> class D_1(B, C): pass
>>> class E_0(D_0): pass
>>> class E_1(D_1): pass
>>> class F(E_0, E_1): pass

然后

>>> [x.__name__ for x in F.__mro__]
['F', 'E_0', 'D_0', 'E_1', 'D_1', 'B', 'C', 'A', 'object']

您会发现,搜索首先是深度,F, E_0, D_0直到遇到遇到共享基类的点为止(B并且C也是的基础)D_1,在该点深度首先侧向到达,E_1然后再从那里开始深度。



所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接:https://www.pythonheidong.com/blog/article/148594/cf099716b2e6bcc00d7b/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

1 0
收藏该文
已收藏

评论内容:(最多支持255个字符)