Подтвердить что ты не робот

Создание класса Python из имени

Итак, у меня есть набор классов и строка с одним из имен классов. Как создать экземпляр класса на основе этой строки?

class foo:
  def __init__(self, left, right):
     self.left = left
     self.right = right

str = "foo"
x = Init(str, A, B)

Я хочу, чтобы x был экземпляром класса foo.

4b9b3361

Ответ 1

Если вы знаете пространство имен, вы можете использовать его напрямую - например, если все классы находятся в модуле zap, словарь vars(zap) - это пространство имен; если они все находятся в текущем модуле, globals(), вероятно, самый удобный способ получить этот словарь.

Если классы не все находятся в одном и том же пространстве имен, а затем создают "искусственное" пространство имен (выделенный dict с именами классов в качестве ключей и объектов класса как значения), как предлагает @Ignacio, вероятно, самый простой подход.

Ответ 2

В вашем случае вы можете использовать что-то вроде

get_class = lambda x: globals()[x]
c = get_class("foo")

И еще проще не получить класс из модуля

import somemodule
getattr(somemodule, "SomeClass")

Ответ 3

classdict = {'foo': foo}

x = classdict['foo'](A, B)

Ответ 4

classname = "Foo"
foo = vars()[classname](Bar, 0, 4)

Или, возможно,

def mkinst(cls, *args, **kwargs):
    try:
        return globals()[cls](*args, **kwargs)
    except:
        raise NameError("Class %s is not defined" % cls)

x = mkinst("Foo", bar, 0, 4, disc="bust")
y = mkinst("Bar", foo, batman="robin")

Различные примечания к фрагменту:

*args и **kwargs являются специальными параметрами в Python, они означают "массив без ключевых слов" и "аргумент ключевых слов" соответственно.

PEP-8 (официальное руководство по стилю Python) рекомендует использовать cls для переменных класса.

vars() возвращает переменную, определенную в локальной области.

globals() возвращает список переменных, которые в настоящее время присутствуют в среде вне локальной области.

Ответ 6

Вы также можете рассмотреть использование метакласса:

Cls = type('foo', (), foo.__dict__)
x = Cls(A, B)

Однако он создает еще один подобный класс.