[英]why is there difference between calling super().foo and super().__getattribute__("foo")
[英]Difference between super() and calling superclass directly
在 Python 2.7 和 3 中,我使用以下方法來調用超類的函數:
class C(B):
def __init__(self):
B.__init__(self)
我看到也可以用super(B, self).__init__()
和 python3 super().__init__()
替換B.__init__(self)
super().__init__()
。
這樣做有什么優點或缺點嗎? 至少對我來說直接從B
調用它更有意義,但也許有一個很好的理由,即super()
只能在使用元類時使用(我通常會避免這種情況)。
對於單繼承, super()
只是引用基類型的一種更高級的方式。 這樣,您可以使代碼更易於維護,例如,如果您想更改基本類型的名稱。 當你到處使用super
,你只需要在class
行中更改它。
真正的好處來自多重繼承。 使用super
,一次調用不僅會自動調用所有基類型的方法(以正確的繼承順序),而且還會確保每個方法只被調用一次。
這基本上允許類型具有菱形屬性,例如您有一個基本類型A
,以及兩個類型B
和C
,它們都源自A
。 然后你有一個從B
和C
繼承的類型D
(使它也從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()
來確保一切正常,而且您不必太擔心。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.