2015-09-16 133 views
2

我想在Python中動態創建類,並且對類和類繼承相對較新。基本上我希望我的最終對象根據不同的需求有不同的歷史類型。我有一個解決方案,但我覺得必須有更好的方法。我夢想着這樣的事情。Python中的條件類繼承

class A: 
    def __init__(self): 
     self.history={} 
    def do_something(): 
     pass 

class B: 
    def __init__(self): 
     self.history=[] 
    def do_something_else(): 
     pass 

class C(A,B): 
    def __init__(self, a=False, b=False): 
     if a: 
      A.__init__(self) 
     elif b: 
      B.__init__(self) 

use1 = C(a=True) 
use2 = C(b=True) 
+3

什麼是語義這裏?你想要「條件繼承」還是你想要「條件初始化」? –

+1

如果use3 = C(a = True,b = True),會發生什麼? – erip

+2

你在這裏試圖做什麼,要麼你說的不好,要麼是一個可怕的想法。說出你正在努力完成的事情,並且很可能有更好的方法。 – msw

回答

3

我假設,由於某種原因,您不能更改A和B,並且您需要兩者的功能。

也許你需要的是兩個不同的類:

class CAB(A, B): 
    '''uses A's __init__''' 

class CBA(B, A): 
    '''uses B's __init__''' 

use1 = CAB() 
use2 = CBA() 

的目標是動態創建一個類。

我不太建議動態地創建一個類。您可以使用一個函數來做到這一點,因爲他們是在模塊的全局命名空間,你可以輕鬆地做事情喜歡泡菜的實例:

def make_C(a=False, b=False): 
    if a: 
     return CAB() 
    elif b: 
     return CBA() 

但是如果你堅持「動態創建類」

def make_C(a=False, b=False): 
    if a: 
     return type('C', (A, B), {})() 
    elif b: 
     return type('C', (B, A), {})() 

和使用兩種方法是:

use1 = make_C(a=True) 
use2 = make_C(b=True) 
+0

謝謝。是否有可能遺漏了多重繼承。我感覺自己正在努力的將會在很多不同的方向發展,我不想讓它變得不可能理解。例如,將會有許多不同類型的歷史記錄,以及這些歷史記錄的許多類型的結果,我想組合這些歷史記錄,並且仍然留有定製空間。我應該用Google搜索什麼? – jamesRH

+1

@ user3790927我不知道你應該google什麼。我假設出於某種原因,您不能更改A和B,並且您需要兩者的功能。你應該做的是選擇最能回答你的問題的答案(因爲你已經提供了答案),並且考慮一些你想做的事情,並且嘗試更好地溝通在你的下一個問題中,或者當你有足夠的代表能夠這樣做的時候訪問我們的Python聊天室。 http://chat.stackoverflow.com/rooms/6/python –

2

你可能並不真正需要的是,這可能是一個XY的問題,但是當你正在學習那些經常發生一種語言。您應該意識到,您通常不需要像使用其他語言一樣使用Python構建龐大的類層次結構。 Python使用「duck typing」 - 如果一個類有你想使用的方法,就調用它吧!

而且,在調用__init__時,實例已經存在。在那個時候你不能(很容易)爲另一個實例改變它(儘管實際上任何事情都是可能的)。

如果你真的希望能夠實例化一個類和接收什麼取決於你傳遞給構造什麼完全不同的對象的基本情況下,簡單,直接的事情是使用返回實例函數不同的班級。

但是,爲了完整性,您應該知道類可以定義__new__方法,該方法在__init__之前調用。這個方法可以返回一個類的實例,或者一個完全不同類的實例,或者任何它想要的東西。因此,舉例來說,你可以這樣做:

class A(object): 
    def __init__(self): 
     self.history={} 
    def do_something(self): 
     print("Class A doing something", self.history) 

class B(object): 
    def __init__(self): 
     self.history=[] 
    def do_something_else(self): 
     print("Class B doing something", self.history) 

class C(object): 
    def __new__(cls, a=False, b=False): 
     if a: 
      return A() 
     elif b: 
      return B() 

use1 = C(a=True) 
use2 = C(b=True) 
use3 = C() 

use1.do_something() 
use2.do_something_else() 

print (use3 is None) 

這適用於任意的Python 2或3。隨着3返回:

Class A doing something {} 
Class B doing something [] 
True