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

Nam*_*nge 43 python multiple-inheritance super

在Python中,如何选择要调用哪个Parent方法?假设我想调用父ASDF2的__init__方法.好像我必须在super()中指定ASDF1 ..?如果我想调用ASDF3 __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
Run Code Online (Sandbox Code Playgroud)

对我来说似乎疯了.我究竟做错了什么?

Fal*_*rri 61

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

class ASDF(ASDF1, ASDF2, ASDF3):
    def __init__(self):
        ASDF2.__init__(self)
Run Code Online (Sandbox Code Playgroud)

  • @ErikAronesty Python 中不存在私有方法的概念,您能澄清一下您的意思吗? (2认同)

Mar*_*cin 10

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

在这里,你有三个父母,__init__从下面看,下一个方法ASDF1ASDF2.一般来说,安全的做法是传递继承列表中的第一个类,super除非你知道为什么要做其他事情.

所有这一切的要点是减轻你必须明确选择__init__要调用的方法.这里的问题是为什么你不想调用所有的超类__init__方法.

关于superpython 的使用有相当多的文献,我建议你google主题,并阅读结果.


Chr*_*ong 6

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

super() 的 Python 2.7 文档

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

class C(B):
    def method(self, arg):
        super(C, self).method(arg)
Run Code Online (Sandbox Code Playgroud)

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

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


在 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)
Run Code Online (Sandbox Code Playgroud)