Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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.

(我在面向对象的Python编程中非常陌生,尤其是在涉及多重继承时,我很难理解super()函数(新样式类)。)

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"

What I don't get is: will the Third() class inherit both constructor methods?

(我不明白的是: Third()类会继承两个构造函数方法吗?)

If yes, then which one will be run with super() and why?

(如果是,那么哪个将与super()一起运行,为什么?)

And what if you want to run the other one?

(如果要运行另一台呢?)

I know it has something to do with Python method resolution order ( MRO ).

(我知道这与Python方法解析顺序( MRO )有关。)

  ask by Callisto translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
432 views
Welcome To Ask or Share your Answers For Others

1 Answer

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

(Guido自己在他的博客文章Method Resolution Order (包括两次较早的尝试)中对此进行了合理的详细说明。)

In your example, Third() will call First.__init__ .

(在您的示例中, Third()将调用First.__init__ 。)

Python looks for each attribute in the class's parents as they are listed left to right.

(从左到右列出,Python会在类的父级中查找每个属性。)

In this case, we are looking for __init__ .

(在这种情况下,我们正在寻找__init__ 。)

So, if you define

(所以,如果您定义)

class Third(First, Second):
    ...

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

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

This situation becomes more complex when inheritance starts crossing paths (for example if First inherited from Second ).

(当继承开始跨越路径时,这种情况变得更加复杂(例如,如果FirstSecond继承)。)

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.

(阅读上面的链接以获取更多详细信息,但是简而言之,Python将尝试维护每个类从子类本身开始在继承列表上出现的顺序。)

So, for instance, if you had:

(因此,例如,如果您有:)

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"

the MRO would be [Fourth, Second, Third, First].

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

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.

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

Edited to add an example of an ambiguous MRO:

(编辑以添加一个模棱两可的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"

Should Third 's MRO be [First, Second] or [Second, First] ?

(Third的MRO应该是[First, Second]还是[Second, First] ?)

There's no obvious expectation, and Python will raise an error:

(没有明显的期望,Python会引发错误:)

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

Edit: 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.

(编辑:我看到一些人争辩说上面的示例缺少super()调用,所以让我解释一下:这些示例的重点是说明MRO的构造方式。)

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.

(您可以-并且当然应该在示例中进行操作,添加super()调用,查看发生了什么,并加深对Python继承模型的了解。)

But my goal here is to keep it simple and show how the MRO is built.

(但是我的目标是保持简单,并说明MRO的构建方式。)

And it is built as I explained:

(正如我所解释的那样:)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...