我需要在Python中动态创建类的实例。基本上我使用 load_module 和检查模块将类导入并加载到类对象中,但我不知道如何创建此类对象的实例。
我找到了将我带到此页面的问题的答案。由于没有人真正提出我的问题的答案,我想我应该发布它。
class k:
pass
a = k()
k2 = a.__class__
a2 = k2()
此时,a和a2都是同一类(k类)的实例。
只需使用三个参数调用内置的“类型”,如下所示:
ClassName = type("ClassName", (Base1, Base2,...), classdictionary)
更新 正如下面的评论所述,这根本不是这个问题的答案。我将保留它不被删除,因为有一些提示有人试图动态创建类 - 这就是上面一行的作用。
要创建类的对象,也有一个引用,正如已接受的答案所示,只需调用该类即可:
instance = ClassObject()
实例化的机制是这样的:
Python 不使用某些语言使用的
new
关键字 - 相反,它的数据模型解释了当使用与任何其他可调用对象相同的语法调用类时用于创建类实例的机制:
调用其类的
__call__
方法(对于类,其类是“元类” - 通常是内置的 type
)。此调用的正常行为是调用正在实例化的类上的(伪)静态 __new__
方法,然后调用其 __init__
。 __new__
方法负责分配内存等,通常由类层次结构根__new__
的object
完成。
因此,调用
ClassObject()
会调用 ClassObject.__class__.call()
(通常为 type.__call__
),此 __call__
方法将接收 ClassObject 本身作为第一个参数 - 纯 Python 实现将如下所示:(当然,cPython 版本是,用 C 语言完成,并带有大量用于极端情况和优化的额外代码)
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__
的任何自定义实现通常都会获得额外参数)
如果您有一个包含要导入的类的模块,您可以这样做。
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()
如果你有一些类对象,你可以通过调用它(带括号)来实例化它。
class MyClass: pass
some_class = MyClass
some_instance = some_class() # -> instance of MyClass
我认为最好的方法是使用
type
。这是一个例子:
>>> class Foo:
... def __init__(self, s):
... self.s = s
...
>>> a = Foo("hello")
>>> a.s
'hello'
>>> b = type(a)("world")
>>> b.s
'world'
>>> assert isinstance(a, Foo)
>>> assert isinstance(b, Foo)
b
是一个与 a
具有相同类型的实例。