Как создать новый экземпляр из объекта класса в Python - PullRequest
57 голосов
/ 08 мая 2011

Мне нужно динамически создать экземпляр класса в Python.В основном я использую модуль load_module и inspect для импорта и загрузки класса в объект класса, но не могу понять, как создать экземпляр этого объекта класса.

Пожалуйста, помогите!

Ответы [ 4 ]

98 голосов
/ 01 октября 2011

Я выяснил ответ на вопрос, который у меня возник, который привел меня на эту страницу. Поскольку никто не предложил ответ на мой вопрос, я решил опубликовать его.

class k:
  pass

a = k()
k2 = a.__class__
a2 = k2()

На данный момент a и a2 являются экземплярами одного и того же класса (класс k).

17 голосов
/ 08 мая 2011

Просто вызовите встроенный «тип», используя три параметра, например:

ClassName = type("ClassName", (Base1, Base2,...), classdictionary)

update , как указано в комментарии ниже, это совсем не ответ на этот вопрос,Я буду держать его как удаленный, поскольку есть некоторые подсказки, которые некоторые люди получают здесь, пытаясь динамически создавать классы - это то, что делает строка выше.

Чтобы создать объект класса, тоже есть ссылка, как указано впринятый ответ, нужно просто вызвать класс:

instance = ClassObject()

Механизм для создания экземпляров таков:

Python не использует ключевое слово new, которое используют некоторые языки - вместо этого это данныеМодель объясняет механизм, используемый для создания мгновенного класса, когда он вызывается с тем же синтаксисом, что и любой другой вызываемый объект:

Вызывается метод его класса '__call__ (в случае класса его классэто «метакласс», который обычно является встроенным type).Обычным поведением этого вызова является вызов (псевдо) статического метода __new__ для экземпляра класса, за которым следует его __init__.Метод __new__ отвечает за выделение памяти и тому подобное, и обычно выполняется __new__ из 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__ обычно получает дополнительные параметры)

3 голосов
/ 08 мая 2011

Так вы можете динамически создать класс с именем 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>
>>>
2 голосов
/ 20 февраля 2013

Если у вас есть модуль с классом, который вы хотите импортировать, вы можете сделать это следующим образом.

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...