2012-08-23 59 views
1

可能重複:
Python dynamic inheritance: How to choose base class upon instance creation?動態派生類在python

我想一個類來選擇基於初始化方法的參數上飛的基類。

Class A(): 
    #... 
Class B(): 
    #... 
Class C(): 
    def __init__(self, base_type): 
     if parent_type == 'A': 
      #TODO: make C derive A 
     else: 
      #TODO: make C derive B 

A和B是派生相同基類的庫類。

a similar question的答案顯得太難看了。

+3

你爲什麼要這樣做?儘管Python等動態語言中可能有很多事情,但這似乎並不是一個好的方法。有了更多的上下文,我們可能能夠更好地瞭解您的問題並提供解決方案。 – cyroxx

+5

你真的需要使用繼承嗎?你可以用組合來代替(例如讓每個C實例擁有A或B的實例)?查看您鏈接的問題的第二個高度評價的答案。 – Blckknght

+5

如果您堅持不使用工廠模式,您可能需要研究元類。 http://docs.python.org/py3k/reference/datamodel.html#metaclasses – dsh

回答

1

我假設你的意思base_type insteand的父類型。但下面應該工作

Class C(): 
    def __init__(self, base_type): 
     if base_type == 'A': 
      self.__class__=A 
     else: 
      self.__class__=B 

這種方法更多的細節可以在這裏找到:http://harkablog.com/dynamic-state-machines.html

+1

downvote的任何原因? – schacki

0

我完全同意cyroxx,你應該給我們一些背景給你的問題。目前,__init__是在創建類的實例以初始化其成員之後調用的。太遲以改變繼承。

會簡單的類工廠,你有足夠的:

class MyA(ABMixin, A): pass 

class MyB(ABMixin, B): pass 

def factory(class_type): 
    if class_type == 'A': 
     return MyA() 
    else: 
     return MyB() 

我建議閱讀this SO answer有關動態類創建的蟒蛇。

2

雖然您可以在__init__改變類,做到在__new__它更合適。前者用於初始化,後者爲建設:

class A(object): pass 
class B(object): pass 

class C(object): 
    def __new__(cls, base_type, *args, **kwargs): 
     return super(C, cls).__new__(base_type, *args, **kwargs) 

assert isinstance(C(A), A) 
assert isinstance(C(B), B) 

隨着__init__,你要創建一個C的實例,然後修改它的類型。通過__new__,您永遠不會創建C實例,只需要創建所需的base_type