3

我正在Google App Engine中製作購物車應用程序。我有一個從基本處理程序派生出許多類:Python:子類可以重載繼承的方法嗎?

class BaseHandler(webapp.RequestHandler): 
    def get(self, CSIN=None): 
     self.body(CSIN) 

這是否意味着每一個派生類的body()方法需要有同樣的說法?這很麻煩。只有一個後代實際上使用該參數。那麼當我添加新的參數時呢?我是否需要通過並改變每一堂課?

class Detail(BaseHandler): 
    def body(self, CSIN): 

class MainPage(BaseHandler): 
    def body(self, CSIN=None): #@UnusedVariable 

class Cart(BaseHandler): 
    def body(self, CSIN): #@UnusedVariable 

回答

6

覆蓋的方法不必具有相同的參數,原則上對方,但他們必須有他們是所謂的具有相同形式參數。因爲任何處理程序可以通過get調用它body,是的,它們必須是相同的。對於這個問題,重寫的一點是調用者不知道對象的確切類,因此如果他們不都具有相同的參數,通常調用者不知道該傳遞什麼。因此,我認爲,用不同的參數覆蓋會是一種不尋常的詭計。

如果您更改其調用的參數,則是,您必須更改要匹配的函數。這與繼承無關,它是Python功能的工作原理。

如果你想多一點靈活性,你可以使用關鍵字參數,這是通過一本字典作爲參數的一個奇特的方式:

class Detail(BaseHandler): 
    def body(self, **kwargs): 
     print kwargs['CSIN'] 

class MainPage(BaseHandler): 
    def body(self, **kwargs): # can ignore kwargs 

class Cart(BaseHandler): 
    def body(self, **kwargs): # can ignore kwargs 

class BaseHandler(webapp.RequestHandler): 
    def get(self, CSIN=None): 
     self.body(CSIN = CSIN, some_new_arg = 3) 

class SomeNewHandler(BaseHandler): 
    def body(self, **kwargs): 
     print kwargs['some_new_arg'] 

我稍微質疑這種智慧的回答:如果你會添加很多新的參數,並且大多數實現忽略大多數參數,然後body可能不是這些參數的函數。也許實際上這些參數是處理程序對象狀態的一部分,你恰好是作爲參數傳遞的。顯然,這種差異是有些主觀的 - 對於每個對象只調用一次的函數,在傳遞字典和使用self作爲字典之間並沒有太大的實際區別。

+0

確實,也許你是對的。我還可以如何訪問這些數據? – 2010-03-08 00:52:43

+0

在調用'body'之前,get可以做'self.CSIN = CSIN',以及任何其他需要的屬性。如果需要的話,處理程序可以讀取'self.CSIN',如果不需要,則不會。只有在CSIN真的是整個請求的一個屬性時才能做到這一點,但不僅僅是這個*特殊*調用body的屬性。如果你可能在同一個處理程序對象上使用不同的CSIN值對'body'進行多次調用,那麼它不是處理程序的屬性,它確實是一個函數參數。否則,如果它使事情乾淨地工作,則可以將所需的任何數據粘貼到處理程序上。 – 2010-03-08 00:58:15

+0

...另一種選擇是讓BaseHandler根據實際需要調用不同的方法。有時你會意識到你已經試圖將太多特殊情況塞進一個抽象概念中,而真正的「身體」在其所有的化身中並沒有達到同樣的目的。這可能不是這種情況,如果唯一的區別是是否需要CSIN來渲染身體,但是如果讓事情失控,它可能會在那裏結束。 – 2010-03-08 01:02:34

2

Python僅基於名稱匹配重載方法。這意味着

class Base: 
    def method(self, param2): 
    print "cheeses" 

class NotBase(Base): 
    def method(self): 
    print "dill" 

obj = NotBase(); 
obj.method() 

將輸出蒔蘿(而obj.method(「東西」)將失敗)。

但是,在你的情況下,這不是理想的行爲。如果使用比基於get方法中的調用所需參數更少的參數來重載body方法,則在這些類上調用get方法將導致錯誤。

+0

「最好的一種正確」 - 非常正確,我的「不一定」是絕望的模糊,並沒有指出,在這種情況下,它變得有必要... – 2010-03-08 01:09:14

+0

好的解決方案。我已經刪除了在我的答案中的參考。 – 2010-03-08 01:20:26