我需要在Python中动态创建一个类的实例。基本上我使用load_module和inspect模块导入并将类加载到类对象中,但我无法弄清楚如何创建此类对象的实例。
请帮忙!
答案 0 :(得分:96)
我想出了我带到这个页面的问题的答案。由于没有人真正提出我的问题的答案,我以为我会发布它。
class k:
pass
a = k()
k2 = a.__class__
a2 = k2()
此时,a和a2都是同一个类的实例(类k)。
答案 1 :(得分:17)
只需使用三个参数调用内置的“类型”,如下所示:
ClassName = type("ClassName", (Base1, Base2,...), classdictionary)
<强>更新强> 正如评论中所述,这根本不是这个问题的答案。我将保留它未删除,因为有一些人在这里试图动态创建类 - 这就是上面的行。
要创建一个类的对象,它也有一个引用,如接受的答案所示,只需要调用该类:
instance = ClassObject()
实例化的机制是:
Python不使用某些语言使用的new
关键字 - 而是它的数据模型解释了在使用与任何其他可调用语法相同的语法调用类时,用于创建类的瞬时的机制:
调用它的类'__call__
方法(在类的情况下,它的类是“元类” - 通常是内置的type
)。此调用的正常行为是在要实例化的类上调用(伪)静态__new__
方法,然后调用其__init__
。 __new__
方法负责分配内存等,通常由__new__
object
来完成,ClassObject()
是类层次结构根。
因此调用ClassObject.__class__.call()
调用type.__call__
(通常为__call__
)此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
方法将接收ClassObject本身作为第一个参数 - 纯Python实现就像这个:( cPython版本当然是在C中完成的,并且有很多额外的角柜和优化代码)
__new__
(我不记得在文档中看到了为根object.__new__
抑制额外参数并将其传递给其他类的确切理由(或机制) - 但它是“在现实生活中”发生的事情 - 如果使用任何额外参数调用__new__
,则会引发类型错误 - 但是,{{1}}的任何自定义实现都会正常获取额外参数。
答案 2 :(得分: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>
>>>
答案 3 :(得分: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()