2011-05-17 105 views
26

可以說我有Python方法重寫,簽名問題?

class Super(): 
    def method1(): 
    pass 

class Sub(Super): 
    def method1(param1, param2, param3): 
     stuff 

這是正確的嗎?將調用method1總是去到子類?我的計劃是有2個子類,每個子類都使用不同的參數覆蓋method1

回答

1

在python中,所有的類方法都是「虛擬的」(就C++而言)。所以,在你的代碼的情況下,如果你想打電話method1()超類,它必須是:

class Super(): 
    def method1(self): 
     pass 

class Sub(Super): 
    def method1(self, param1, param2, param3): 
     super(Sub, self).method1() # a proxy object, see http://docs.python.org/library/functions.html#super 
     pass 

和方法簽名事做。你不能把這樣的方法:

sub = Sub() 
sub.method1() 
25

Python會允許這樣做,但如果method1()旨在從外部代碼執行,那麼你可能要重新考慮這一點,因爲它違反了LSP等都不會始終正常工作。

+0

是LSP的上Sub.method1接受3個參數,而Super.method1發生的事實,違反了無其實不同使他們接口? – Unode 2011-05-18 16:59:55

+1

@Unode:正確。這可以通過讓子類的方法的參數全部具有默認值來解決,但是然後您得到哪些默認值是合適的。 – 2011-05-18 17:02:14

+2

我明白了。但後來只是爲了澄清。如果父方法1被定義爲'Super.method1(param1 = None,param2 = None,param3 = None)',它仍然會違反LSP,如果它在子類上被定義爲'Sub.method1(param1,param2,param3)'right?由於屬性在一個案例中是強制性的,而不是另一個。因此,根據我的理解,在不更改子類接口的情況下,不違反LSP的唯一方法是使父類中沒有默認值的參數。我是否正確或過度解釋LSP? – Unode 2011-05-18 18:44:17

-2

是的。調用「method1」將始終轉到子類。 Python中的方法簽名只包含名稱而不包含參數列表。

+2

錯誤的答案。方法簽名總是很重要,因爲沒有函數重載,因爲它發生在C/C++中。 – 2011-05-17 17:33:52

+0

我的意思是,Python不考慮參數列表來決定調用哪種方法,但是我認爲從_that_角度看它是正確的! – Elektito 2011-05-17 17:38:08

1

你可以做這樣的事情,如果它是確定使用默認參數:

>>> class Super(): 
... def method1(self): 
...  print("Super") 
... 
>>> class Sub(Super): 
... def method1(self, param1="X"): 
...  super(Sub, self).method1() 
...  print("Sub" + param1) 
... 
>>> sup = Super() 
>>> sub = Sub() 
>>> sup.method1() 
Super 
>>> sub.method1() 
Super 
SubX