Python的super()如何与多重继承一起使用? [英] How does Python's super() work with multiple inheritance?

查看:449
本文介绍了Python的super()如何与多重继承一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在面向对象的Python编程中非常新,遇到了麻烦 了解super()函数(新样式类),尤其是涉及多重继承时.

I'm pretty much new in Python object oriented programming and I have trouble understanding the super() function (new style classes) especially when it comes to multiple inheritance.

例如,如果您有类似的东西:

For example if you have something like:

class First(object):
    def __init__(self):
        print "first"

class Second(object):
    def __init__(self):
        print "second"

class Third(First, Second):
    def __init__(self):
        super(Third, self).__init__()
        print "that's it"

我不明白的是:Third()类会继承这两个构造方法吗?如果是,那么哪个将与super()一起运行,为什么?

What I don't get is: will the Third() class inherit both constructor methods? If yes, then which one will be run with super() and why?

如果要运行另一个,该怎么办?我知道它与Python方法解析顺序有关( MRO ).

And what if you want to run the other one? I know it has something to do with Python method resolution order (MRO).

推荐答案

Guido自己在其博客文章

This is detailed with a reasonable amount of detail by Guido himself in his blog post Method Resolution Order (including two earlier attempts).

在您的示例中,Third()将调用First.__init__.从左到右列出,Python会在类的父级中查找每个属性.在这种情况下,我们正在寻找__init__.因此,如果您定义

In your example, Third() will call First.__init__. Python looks for each attribute in the class's parents as they are listed left to right. In this case, we are looking for __init__. So, if you define

class Third(First, Second):
    ...

Python首先查看First,如果First没有该属性,则它将查看Second.

Python will start by looking at First, and, if First doesn't have the attribute, then it will look at Second.

当继承开始跨越路径时(例如,如果First是从Second继承的),这种情况会变得更加复杂.阅读上面的链接以获取更多详细信息,但是简而言之,Python会尝试维护每个类从子类本身开始在继承列表上出现的顺序.

This situation becomes more complex when inheritance starts crossing paths (for example if First inherited from Second). Read the link above for more details, but, in a nutshell, Python will try to maintain the order in which each class appears on the inheritance list, starting with the child class itself.

例如,如果您有:

class First(object):
    def __init__(self):
        print "first"

class Second(First):
    def __init__(self):
        print "second"

class Third(First):
    def __init__(self):
        print "third"

class Fourth(Second, Third):
    def __init__(self):
        super(Fourth, self).__init__()
        print "that's it"

MRO为[Fourth, Second, Third, First].

顺便说一句:如果Python无法找到一致的方法解析顺序,它将引发一个异常,而不是退回到可能使用户感到惊讶的行为上.

By the way: if Python cannot find a coherent method resolution order, it'll raise an exception, instead of falling back to behavior which might surprise the user.

编辑后添加了一个模棱两可的MRO的示例:

Edited to add an example of an ambiguous MRO:

class First(object):
    def __init__(self):
        print "first"

class Second(First):
    def __init__(self):
        print "second"

class Third(First, Second):
    def __init__(self):
        print "third"

Third的MRO应该是[First, Second]还是[Second, First]?没有明显的期望,Python会引发错误:

Should Third's MRO be [First, Second] or [Second, First]? There's no obvious expectation, and Python will raise an error:

TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution order (MRO) for bases Second, First

我看到几个人争辩说上面的示例缺少super()调用,所以让我解释一下:这些示例的目的是说明MRO的构造方式.它们不是用于打印第一\第二\第三"或其他内容.您可以-并且当然应该玩这个例子,添加super()调用,看看会发生什么,并加深对Python继承模型的了解.但我的目标是保持简单,并说明MRO的构建方式.正如我所解释的那样:

I see several people arguing that the examples above lack super() calls, so let me explain: The point of the examples is to show how the MRO is constructed. They are not intended to print "first\nsecond\third" or whatever. You can – and should, of course, play around with the example, add super() calls, see what happens, and gain a deeper understanding of Python's inheritance model. But my goal here is to keep it simple and show how the MRO is built. And it is built as I explained:

>>> Fourth.__mro__
(<class '__main__.Fourth'>,
 <class '__main__.Second'>, <class '__main__.Third'>,
 <class '__main__.First'>,
 <type 'object'>)

这篇关于Python的super()如何与多重继承一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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