2011-10-20 177 views
4

我在超類中有一個函數,它返回它自己的新版本。我有這個超類的子類繼承特定的功能,但寧願它返回一個新版本的子類。我該如何編寫代碼,以便函數調用來自父代時,它將返回父代的一個版本,但是當它從子代中調用時,它會返回新版本的代碼?Python繼承:返回子類

+0

你爲什麼必須區分類型。繼承的一個特點是一個子類的實例可以作爲它的超類的一個實例。 –

+0

該函數存在於父項中。它返回一個新的對象。如果我返回父對象的一個​​實例,那麼它不能訪問子對象的函數。但是我不能只是返回孩子,因爲那時沒有其他孩子可以使用這個函數(而且父母也不能)。所以我想返回一個調用它的實例。 – user592419

回答

6

如果new不依賴於self,使用一個類方法:

class Parent(object): 
    @classmethod 
    def new(cls,*args,**kwargs): 
     return cls(*args,**kwargs) 
class Child(Parent): pass 

p=Parent() 
p2=p.new() 
assert isinstance(p2,Parent) 
c=Child() 
c2=c.new() 
assert isinstance(c2,Child) 

或者,如果new不依賴於self,使用type(self)確定self的類:

class Parent(object): 
    def new(self,*args,**kwargs): 
     # use `self` in some way to perhaps change `args` and/or `kwargs` 
     return type(self)(*args,**kwargs) 
+0

如果第二種方法也適用於這種情況,那麼在哪種情況下應該使用第一種方法?只是爲了讓讀者更清楚'new'不會改變'self'和/或'args' /'kwargs'嗎? – nivk

+0

@nivk:classmethod的主要用途之一是[定義「替代構造函數」](https://stackoverflow.com/a/1950927/190597)。只要這是一個易於理解的約定,那麼爲您閱讀代碼的其他人也會遵守這一慣例。 – unutbu

+0

在這種情況下,由於其靈活性,似乎應該首選第二種方法。我不認爲OP需要在鏈接中顯示的意義上的替代構造函數(並且我的使用案例並沒有將我帶到這裏)。有什麼我錯過了,應該更喜歡第一種方法嗎? – nivk