如何从Python中的类对象创build一个新的实例
我需要dynamic地在Python中创build一个类的实例。 基本上我使用load_module和inspect模块来导入和加载到类对象,但我不知道如何创build这个类对象的实例。
请帮忙!
我想出了我带到这个页面的问题的答案。 由于没有人真的提出了我的问题的答案,我想我会发布。
class k: pass a = k() k2 = a.__class__ a2 = k2()
此时,a和a2都是同一类(k类)的实例。
只需使用三个参数调用内置的“types”,如下所示:
ClassName = type("ClassName", (Base1, Base2,...), classdictionary)
如下面的评论所述的更新 ,这根本不是这个问题的答案。 我会保持它不被删除,因为有些提示有些人试图dynamic创build类 – 这是上面的行。
创build一个类的对象也有一个参考,正如放在接受的答案,只需要调用类:
instance = ClassObject()
实例化的机制是这样的:
Python不使用某些语言使用的new
关键字 – 而是它的数据模型解释了当使用与其他可调用语法相同的语法调用时,用于创build类的瞬间的机制:
它的类__call__
方法被调用(在类的情况下,它的类是“元类” – 通常是内置type
)。 这个调用的正常行为是调用被实例化的类的(伪)静态__new__
方法,然后是__init__
。 __new__
方法负责分配内存等,通常由类层次结构根object
__new__
完成。
所以调用ClassObject()
调用ClassObject.__class__.call()
(通常是type.__call__
),这个__call__
方法将接收ClassObject本身作为第一个参数 – 纯Python的实现将是这样的:(当然,cPython版本,在C中完成,并有很多额外的代码angular落和优化)
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__
任何额外的参数,它会引发一个types错误 – 但是, __new__
任何自定义实现通常会得到额外的参数)
这是你如何可以dynamic地在代码中创build一个名为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> >>>
如果你有一个你想导入的类的模块,你可以这样做。
module = __import__(filename) instance = module.MyClass()
如果您不知道该类是什么types的,则可以遍历模块中可用的类。
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()