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

时间:2013-01-07 23:40:02

标签: 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

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

3 个答案:

答案 0 :(得分:55)

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

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

答案 1 :(得分:10)

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

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

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

关于在{python}中使用super的文章相当多,我建议你google主题,并阅读结果。

答案 2 :(得分:3)

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

Python 2.7 documentation for super()

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

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

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

当确定方法解析顺序(MRO)时,超级跳过作为第一个参数传入的类,并开始查看该类'父母和兄弟姐妹。因此,当您将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)