對於Python 2.5及更高版本,使用新樣式類,以下代碼片段用於調用子類中的繼承方法有什麼區別?在子類中調用繼承方法的區別?
class A(object):
def foo(self):
pass
class B(A):
def __init__(self):
self.foo()
class C(A):
def __init__(self):
super(C, self).foo()
對於Python 2.5及更高版本,使用新樣式類,以下代碼片段用於調用子類中的繼承方法有什麼區別?在子類中調用繼承方法的區別?
class A(object):
def foo(self):
pass
class B(A):
def __init__(self):
self.foo()
class C(A):
def __init__(self):
super(C, self).foo()
只要你正在處理像你給的例子那樣的單繼承類, 沒有太大的區別。無論哪種情況,python都會使用方法解析順序(mro) (您可以通過打印C.__mro__
來檢查)以找出方法 foo的第一次發生。這些都解決你的基類,A的foo實現。
但是,當你有多重繼承時,事情會變得有趣。請看下面的 例如:
class W(object):
def foo(self):
print "W"
class X(W):
def foo(self):
#super(X,self).foo()
W.foo(self)
print "X"
class Y(W):
def foo(self):
print "Y"
class Z(X,Y):
def __init__(self):
self.foo()
Z.__mro__
z = Z()
如果你看一下X類,我們可以用超級調用X的基類,或者我們 可以使用直接調用基類W.的區別是,當使用超級時,python 不尋找具體的實現,而是當前mro列表中的第一個實現 。用於Z的MRO列表是:
(Z,X,Y,W)
因此,使用超一將打印: Y X
而這直接調用基的一個將打印: W X
基本上,使用超級動態調用在MRO第一實施中發現,而class.foo(或在您的情況下的self.foo)調用該特定的方法。
所不同的是,B
後代可以適當參與多態性,因爲如果覆蓋了它們foo()
方法將被調用,而C
沒有這個選項。
假設B
本身定義foo
方法,然後將self.foo()
調用foo
B
的版本。在C
的實現中,super
調用確保調用A
的foo
版本,即使C
也定義了foo
。