2012-09-17 37 views
0

好的。我一直在努力解決這個問題。 我有一個子類。我希望它創建它的基類的一個實例,如果它被調用時某些事情是真的。我會用__ new __做這個嗎?如果是的話,我會怎麼樣?如何創建與被調用的類不同的類?

這是我的意思的例子:

import warnings 
class A: 
    def __init__(self, *args): 
     self.val = list(args) 
    def __str__(self): 
     return "A" 

class B(A): 
    def __init__(self, *args): 
     if len(args)==3: 
      A.__init__(self, *args) 
      return 
     else: 
      warnings.warn("Making an A object!") 
      return A(*args) 

    def __str__(self): 
     return "B" 
    def extramethod1(self): 
     print "This method is only in a B object" 

x = B(1, 2, 3) 
Warning (from warnings module) 
    File '/test.py', line 14 
UserWarning: Making an A object! 
y = B(1, 2) 
print x, y 
'A B' 
y.extramethod1() 
'This method is only in a B object' 

另外,我怎麼會具有B-問題,當它這樣做的警告?

+0

B的構造函數在哪裏?你應該在那裏定義init邏輯。 –

+0

可能重複的[應該類的構造函數返回一個子類?](http://stackoverflow.com/questions/12433584/should-a-class-constructor-return-a-subclass) – BrenBarn

+0

您不是一個A對象!你讓兩次都是B對象。 – jimifiki

回答

0

__init__應該返回無!不是對象!

你可以嘗試不同的方法:

def f(*largs,**kwargs): 
    if (...): 
     return A(*largs,**kwargs) 
    return B(*largs,**kwargs) 

x = f(1,2,3) 
y = f(1,2) 

你可能最終使爲F b的靜態方法,以便把它綁定到類

1

this previous question。那是在相反的方向提出這個問題:超類是否應該返回一個子類實例。但答案是一樣的:使用工廠函數。

+0

工廠在這種情況下是常見的和預期的。另外,像'my_instance = B(1,2,3)'這樣的代碼似乎很髒,然後調用'isinstance(my_instance,B)'並查看答案'False'! – anregen

0

不管你的動機這樣做,在Python中,只要您撥打一個電話,以創建一個類的實例,所謂是:

在類的元類的__call__方法。也就是說usualy「type.__call__ - 定製的很少使用元類重寫此

那個函數,反過來,調用類的__new__對象__new__返回一個對象,它是創建的實例 - 。它可以從調用,它的類小號超,一個subblass,或任何其他Python對象。(包括None當一個人忘記,包括在__new__方法適當return聲明恰好soemtimes。元類的__call__他們調用新對象的__init__方法。

對於你的目的,簡單的方法就是寫出你的方法,並讓它返回你的翅膀更適合。請注意,返回值__init__總是被忽略(因此應隱含None不會誤導任何人閱讀代碼)。

相關問題