我需要在Python中动态创建一个类的实例。基本上我使用了load_module和inspect模块来导入和加载类到一个类对象中,但是我无法弄清如何创建这个类对象的实例。
我找到了答案,解决了我来到这个页面的问题。由于没有人提供我想要的答案,所以我决定发布出来。
class k:
pass
a = k()
k2 = a.__class__
a2 = k2()
此时,a和a2都是同一个类(k类)的实例。
a3 = k2(7)
将其翻译为:
a3 = k2(7)
- gerardwk2 = a.__class__
和 k2 = k
有什么区别? - Joshua Coadyk2
是对象类型,在这种情况下是 a
的类型 (a.__class
),k2()
创建该类型的新对象实例,与 a
独立。k2 = k
只是创建了对相同实例的新引用。 - pixelouk2 = type(a)
获取类对象,然后调用该类对象 a2 = k2()
。这本质上是相同的,但你不必在代码中使用那些丑陋的双下划线... 这样可能更具可移植性。 - robert只需要使用三个参数调用内置的"type"函数,就像这样:
ClassName = type("ClassName", (Base1, Base2,...), classdictionary)
更新:如下评论所述,这并不是完全回答此问题的答案。我将保留它未删除,因为有一些人会尝试动态创建类 - 这就是上面一行代码的作用。
要创建一个已经有引用的类的对象,按照被接受的答案所述,只需要调用该类即可:
instance = ClassObject()
Python的实例化机制如下:
Python没有像其他某些编程语言一样使用new
关键字,而是通过其数据模型解释了创建类实例的机制。当按照与任何其他可调用对象相同的语法调用它时,将调用其类的__call__
方法(在类的情况下,其类是“元类”,通常为内置type
)。这个调用的普通行为是调用被实例化的类上的(伪)静态__new__
方法,然后调用其__init__
方法。 __new__
方法负责分配内存等任务,并通常由object
的__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__
实现通常会获得额外参数)
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()
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()
我认为最好的方法是使用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
类型相同的实例。
class MyClass: pass
some_class = MyClass
some_instance = some_class() # -> instance of MyClass
instance = Class()
...(注:这是一行Python代码,意思是创建一个类的实例对象并将其赋值给名为"instance"的变量。) - Jochen Ritzel