54

在 Python 中,我如何选择调用哪个 Parent 的方法?假设我想调用父 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

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

4

3 回答 3

80

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

class ASDF(ASDF1, ASDF2, ASDF3):
    def __init__(self):
        ASDF2.__init__(self)
于 2013-01-07T23:45:16.027 回答
10

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

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

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

有相当多的关于super在 python 中使用的文献,我建议你谷歌这个主题,并阅读什么结果。

于 2013-01-07T23:46:40.303 回答
6

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

super() 的 Python 2.7 文档

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

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

请注意,这里 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)
于 2014-09-10T20:53:25.887 回答