2011-05-08 86 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() 
相关问题