2011-05-08 83 views
42

我需要在Python中動態創建類的實例。基本上我使用load_module和inspect模塊來導入和加載類到一個類對象,但我無法弄清楚如何創建這個類對象的實例。如何從Python中的類對象創建新實例

請幫忙!

+5

什麼? 'instance = Class()'... – 2011-05-08 00:25:20

+0

我想你想動態創建一個新類。不是給定類的對象。 – jsbueno 2011-05-08 00:44:15

+0

新實例表示在內存中有自己空間的新對象。大多數語言都使用'new'關鍵字,以便明確指出該對象是新的,並且新實例的(對象)屬性不會被另一個實例引用/共享。 – BillR 2013-05-08 17:36:40

回答

12

就叫「類型」建成使用三個參數,如下所示:

ClassName = type("ClassName", (Base1, Base2,...), classdictionary) 

更新 作爲評論說波紋管這不是回答這個問題的。我會保持它不被刪除,因爲有些提示有些人試圖動態創建類 - 這就是上面所說的。

要創建一個類之一的對象的引用也一樣,放在接受的答案,一個只需要調用類:

instance = ClassObject() 

實例化的機制是這樣的:

Python不使用某些語言使用的new關鍵字 - 而是它的數據模型解釋了用於創建類的瞬間時使用與其他可調用語法相同的語法創建類的瞬間機制:

其類'__call__方法被調用(在類的情況下,其類是「元類」 - 通常是內置的type)。此調用的正常行爲是調用正在實例化的類的(僞)靜態__new__方法,然後調用__init____new__方法負責分配內存等,通常由object__new__完成,它是類層次結構根。

所以調用ClassObject()調用ClassObject.__class__.call()(通常會type.__call__)這__call__方法將收到ClassObject本身作爲第一個參數 - 一個純Python實現是這樣的:(CPython的版本是當然的,在C完成,有很多的額外代碼cornercases和優化)

class type: 
    ... 
    def __call__(cls, *args, **kw): 
      constructor = getattr(cls, "__new__") 
      instance = constructor(cls) if constructor is object.__new__ else constructor(cls, *args, **kw) 
      instance.__init__(cls, *args, **kw) 
      return instance 

抑制額外的參數,以根__new__並將它傳遞給其他類(我不記得看到在文檔的確切理由(或機構) - 但它是「現實生活中發生的事情」 - 如果object.__new__被稱爲任何額外的參數它會引發一個類型錯誤 - 然而,__new__的任何自定義實現通常會得到額外的參數)

+6

OP是不是想創建一個實例,而不是一個類? – Keith 2011-05-08 05:04:11

3

這是如何在代碼中動態創建名爲Child的類,假設Parent已經存在......即使您沒有明確的Parent類,您可以使用object ...

下面的代碼定義了__init__(),然後將其與類相關聯。

>>> child_name = "Child" 
>>> child_parents = (Parent,) 
>>> child body = """ 
def __init__(self, arg1): 
    # Initialization for the Child class 
    self.foo = do_something(arg1) 
""" 
>>> child_dict = {} 
>>> exec(child_body, globals(), child_dict) 
>>> childobj = type(child_name, child_parents, child_dict) 
>>> childobj.__name__ 
'Child' 
>>> childobj.__bases__ 
(<type 'object'>,) 
>>> # Instantiating the new Child object... 
>>> childinst = childobj() 
>>> childinst 
<__main__.Child object at 0x1c91710> 
>>> 
76

我想出了我帶到這個頁面的問題的答案。由於沒有人真的提出了我的問題的答案,我想我會發布它。

class k: 
    pass 

a = k() 
k2 = a.__class__ 
a2 = k2() 

此時,a和a2都是同一類(k類)的實例。

+1

這似乎是正確的答案。工程,它很簡單。 – 2015-03-03 18:40:59

+0

注意如果__init__接受它們,你也可以傳遞參數給構造函數 'a3 = k2(7)' – gerardw 2016-10-25 21:26:35

+0

'k2 = a .__ class__'和'k2 = k'有什麼區別? – 2017-03-25 22:32:09

2

如果你有一個你想要導入的類的模塊,你可以這樣做。

module = __import__(filename) 
instance = module.MyClass() 

如果您不知道什麼類被命名,您可以遍歷模塊中可用的類。

import inspect 
module = __import__(filename) 
for c in module.__dict__.values(): 
    if inspect.isclass(c): 
     # You may need do some additional checking to ensure 
     # it's the class you want 
     instance = c() 
相關問題