Python 的多重继承:选择调用哪个 super()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14206015/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:45:29  来源:igfitidea点击:

Python's Multiple Inheritance: Picking which super() to call

pythonmultiple-inheritancesuper

提问by Name McChange

In Python, how do I pick which Parent's method to call? Say I want to call the parent ASDF2's __init__method. Seems like I have to specify ASDF1in the super()..? And if I want to call ASDF3's __init__, then I must specify ASDF2?!

在 Python 中,如何选择要调用的父方法?假设我想调用父 ASDF2 的__init__方法。好像我必须在 super().. 中指定ASDF1?如果我想调用 ASDF3's __init__,那么我必须指定ASDF2?!

>>> class ASDF(ASDF1, ASDF2, ASDF3):
    def __init__(self):
        super(ASDF1, self).__init__()


>>> ASDF()
ASDF2's __init__ happened
>>> class ASDF(ASDF1, ASDF2, ASDF3):
    def __init__(self):
        super(ASDF2, self).__init__()


>>> ASDF()
ASDF3's __init__ happened

Seems bonkers to me. What am I doing wrong?

对我来说似乎很疯狂。我究竟做错了什么?

采纳答案by Falmarri

That's not what super()is for. Super basically picks one (or all) of its parents in a specific order. If you only want to call a single parent's method, do this

那不是super()为了什么。Super 基本上按特定顺序选择一个(或全部)其父项。如果您只想调用单亲的方法,请执行此操作

class ASDF(ASDF1, ASDF2, ASDF3):
    def __init__(self):
        ASDF2.__init__(self)

回答by Marcin

supercalls the next method in the method resolution order. In a linear inheritance tree, that will be method from the immediately parent class.

super调用方法解析顺序中的下一个方法。在线性继承树中,这将是来自直接父类的方法。

Here, you have three parents, and the next __init__method from ASDF1's perspective is that of ASDF2. In general, the safe thing to do is to pass the first class in the inheritance list to superunless you know why you want to do something else.

在这里,你有三个父母,接下来__init__从方法ASDF1的角度来看是的ASDF2。通常,安全的做法是将继承列表中的第一个类传递给 ,super除非您知道为什么要执行其他操作。

The point of all of this is to relieve you of having to explicitly pick which __init__methods to call. The question here is why you don't want to call all of the superclass __init__methods.

所有这一切的目的是让您不必明确选择__init__要调用的方法。这里的问题是为什么您不想调用所有超类__init__方法。

There's a fairly substantial literature on the use of superin python, and I recommend that you google the topic, and read what results.

有大量关于super在 python 中使用的文献,我建议您在 google 上搜索该主题,并阅读结果。

回答by Christian Long

You are passing ASDF1 (one of your parent classes) as the first argument to super(). Don't do that. Instead, you should pass ASDF as the first argument to super().

您将 ASDF1(您的父类之一)作为 super() 的第一个参数传递。不要那样做。相反,您应该将 ASDF 作为第一个参数传递给 super()。

Python 2.7 documentation for super()

super() 的 Python 2.7 文档

To quote the Python 2.7 docs, a typical superclass call looks like this:

引用 Python 2.7 文档,典型的超类调用如下所示:

class C(B):
    def method(self, arg):
        super(C, self).method(arg)

Notice that the first argument to super here is C, which is the current class. Don't pass B (the parent class) to super().

注意这里 super 的第一个参数是 C,它是当前类。不要将 B(父类)传递给 super()。

When determining the Method Resolution Order (MRO) super skips the class that is passed in as its first argument, and starts looking at that class' parents and siblings. So, when you passed ASDF1 as the first argument to super(), it skipped over ASDF1 and started its search with ASDF2. That's why ASDF2's __init__was called.

在确定方法解析顺序 (MRO) 时,super 会跳过作为其第一个参数传入的类,并开始查看该类的父级和兄弟级。因此,当您将 ASDF1 作为第一个参数传递给 super() 时,它会跳过 ASDF1 并开始使用 ASDF2 进行搜索。这就是 ASDF2__init__被称为的原因。



In Python 3, you don't have to pass the current class any more.

在 Python 3 中,您不必再传递当前类。

class C(B):
    def method(self, arg):
        super().method(arg)    # This does the same thing as:
                               # super(C, self).method(arg)
                               # (Python 3 only)