首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mro订单深度优先还是广度优先?

mro订单深度优先还是广度优先?
EN

Stack Overflow用户
提问于 2017-11-05 01:28:13
回答 1查看 1.8K关注 0票数 14

简单地说是Python的

在类中查找属性名本质上是通过访问左向右、深度一阶中的祖先类来实现的。

然而,

代码语言:javascript
复制
>>> 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__列出的不是深度优先的类,而是广度优先的类。我是不是误解了什么?谢谢。

EN

回答 1

Stack Overflow用户

发布于 2017-11-05 02:27:02

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

深度-首先,直到遇到将共享父级的类,然后是宽度-首先在这些类中。

虽然这是一个非常松散的特点。

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

简单示例-深度优先

代码语言:javascript
复制
>>> 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

然后

代码语言:javascript
复制
>>> [x.__name__ for x in c.__mro__]
['c', 'b_0', 'a_0', 'b_1', 'a_1', 'object']

共享基础示例-深度然后是宽度

请注意,在您的示例中,您有一个共享父级(A),它使BC首先以一种宽的方式遍历。如果您有一个越来越复杂的层次结构:

代码语言:javascript
复制
>>> 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

然后

代码语言:javascript
复制
>>> [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,直到它到达遇到共享基类的点(BC也是D_1的基),在这一点上,深度首先是指向E_1,然后再从那里返回深度。

票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47117327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档