Python类继承调用顺序 [英] Python class inheritance call order

查看:58
本文介绍了Python类继承调用顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个著名的Python示例

There is a famous Python example

class A(object):
    def go(self):
        print("go A go!")

class B(A):
    def go(self):
        super(B, self).go()
        print("go B go!")

class C(A):
    def go(self):
        super(C, self).go()
        print("go C go!")

class D(B,C):
    def go(self):
        super(D, self).go()
        print("go D go!")


d = D()
d.go() 

#go A go!
#go C go!
#go B go!
#go D go!

我有几个问题。第一个是B呼叫A,C呼叫A,所以我希望A出现两次。第二个问题是关于顺序的。

I have several questions. The first one is B calls A and C calls A so I expect A to appear twice. The second question is about the order.

推荐答案

自Python 2.3开始,方法解析就使用了一种称为C3线性化的算法(从Dylan借来) )。 Wikipedia上有一篇不错的文章

Since Python 2.3, method resolution has used an algorithm called C3 Linearization (borrowed from Dylan). Wikipedia has a nice article on it.

顾名思义,该想法是强制将方法分辨率图变为直线,即使继承图不是。这意味着 A 在设计上不会出现两次。

As the name implies, the idea is to force the method resolution graph to be a straight line, even if the inheritance graph isn't. Which means A is not going to appear twice, by design.

为什么?好吧,一方面,它完全避免了困扰许多其他语言中多重继承的钻石问题。 (或者说许多其他语言禁止MI或将其限制为纯接口,也许更准确,因为它们没有解决C ++中存在的问题的方法。)

Why? Well, for one thing, it completely avoids the "diamond problem" that plagues multiple inheritance in many other languages. (Or maybe it's more accurate to say that many other languages either ban MI or restrict it to pure "interfaces" because they didn't have a solution to the problem as it exists in C++.)

原始Python解释(包括其背后的动机)在 Python 2.3方法解析顺序。这有点技术性,但是如果您有兴趣的话值得阅读。

The original Python explanation—including the motivation behind it—is available in The Python 2.3 Method Resolution Order. This is a bit technical, but worth reading if you're interested.

您可能还想阅读原始Dylan论文,其中详细介绍了非线性问题的原因MRO图,以及提出单调线性化的挑战(即,按照您期望的顺序进行,或者至少克服线性关系后,您期望的顺序),等等。

You might also want to read the original Dylan paper, which goes into more detail about what's wrong with non-linear MRO graphs, and the challenges of coming up with a linearization that's monotonic (i.e., it goes in the order you expect, or at least the order you expect once you get over the fact that it's linear), and so on.

如果您想更深入地了解 type()的工作原理,或者只是想了解一下两者之间的变化, 2.3和3.7(例如, __ mro __ 的创建和更新方式-尽管魔术3.x super 在其他位置),确实没有比 CPython源代码更好的地方了。

And if you want a deeper understanding of how type() works under the covers, or just want to see what's changed between 2.3 and 3.7 (e.g., the way __mro__ gets created and updated—although magic 3.x super is elsewhere), there's really no better place than the CPython source.

这篇关于Python类继承调用顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆