Мне нужно динамически создать экземпляр класса в Python. В основном я использую load_module и проверяю модуль на импорт и загрузку класса в объект класса, но я не могу понять, как создать экземпляр этого объекта класса.
Пожалуйста, помогите!
Мне нужно динамически создать экземпляр класса в 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__
of object
, который является корнем иерархии классов.
Таким образом, вызов ClassObject()
вызывает ClassObject.__class__.call()
(который обычно будет type.__call__
), этот метод __call__
получит сам ClassObject в качестве первого параметра - реализация Pure 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 the class you want
instance = c()