在Python 2.7和3中,我使用以下方法来调用超类的函数:
class C(B):
def __init__(self):
B.__init__(self)
我发现也可以将B.__init__(self)
替换为super(B, self).__init__()
和python3 super().__init__()
。
这样做有什么优点或缺点吗?至少从B
直接为我调用它更有意义,但也许有一个很好的理由super()
只能在使用元类时使用(我通常会避免)。
答案 0 :(得分:48)
对于单继承,super()
只是引用基类型的一种更有趣的方式。这样,您可以使代码更易于维护,例如,如果您想要更改基本类型的名称。当您在任何地方使用super
时,只需在class
行中进行更改。
但真正的好处在于多重继承。使用super
时,单个调用不仅会自动调用所有基类型的方法(按照正确的继承顺序),而且还会确保每个方法只调用一次
这实质上允许类型具有diamond属性,例如您有一个基本类型A
,以及两个类型B
和C
,它们都来自A
。然后,您有一个类型D
,它继承自B
和C
(使其隐含地继承自A
两次)。如果你现在明确地调用基类型的方法,你将最终调用A的方法两次。但是使用super
,它只会调用一次:
class A (object):
def __init__ (self):
super().__init__()
print('A')
class B (A):
def __init__ (self):
super().__init__()
print('B')
class C (A):
def __init__ (self):
super().__init__()
print('C')
class D (C, B):
def __init__ (self):
super().__init__()
print('D')
当我们现在实例化D
时,我们得到以下输出:
>>> D()
A
B
C
D
<__main__.D object at 0x000000000371DD30>
现在,让我们再次手动调用基类型的方法来完成所有这些:
class A2 (object):
def __init__ (self):
print('A2')
class B2 (A2):
def __init__ (self):
A2.__init__(self)
print('B2')
class C2 (A2):
def __init__ (self):
A2.__init__(self)
print('C2')
class D2 (C2, B2):
def __init__ (self):
B2.__init__(self)
C2.__init__(self)
print('D2')
这是输出:
>>> D2()
A2
B2
A2
C2
D2
<__main__.D2 object at 0x0000000003734E48>
如您所见,A2
出现两次。这通常不是你想要的。当您手动调用使用super
的某个基类型的方法时,它会变得更加混乱。因此,您应该使用super()
来确保一切正常,同时也不必过于担心。