2013-01-07 35 views
33

在Python中,如何选择调用哪个Parent的方法?假设我想调用父ASDF2的__init__方法。似乎我必须指定ASDF1在超()..?如果我想打电话给ASDF3的__init__,那么我必须指定ASDF2?!Python的多重继承:选择要调用哪个super()

>>> 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 

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

回答

47

这不是super()的用途。 Super基本上以特定的顺序挑选一个(或全部)父母。如果你只想要把一个单亲的方法,这样做

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

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

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

所有这一切的目的是为了减轻你不得不明确选择哪个方法来调用。这里的问题是为什么你不想调用所有的超类__init__方法。

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

4

你传递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) 

注意,第一个参数超级这里是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)