Учитывая строку в качестве пользовательского ввода в функцию Python, я хотел бы извлечь из нее объект класса, если в текущем определенном пространстве имен есть класс с таким именем. По сути, я хочу реализацию для функции, которая даст такой результат:
class Foo:
pass
str_to_class("Foo")
==> <class __main__.Foo at 0x69ba0>
Это вообще возможно?
Ответы:
Это кажется самым простым.
источник
Это может сработать:
источник
def str_to_class(str): return vars()[str]
?Вы могли бы сделать что-то вроде:
источник
globals()
... еще одну вещь, которую следует избегатьglobals()
, возможно, гораздо менее плох, чемeval
, и не намного хуже, чемsys.modules[__name__]
AFAIK.Вы хотите класс
Baz
, который живет в модулеfoo.bar
. Вы хотите использовать Python 2.7, такimportlib.import_module()
как это облегчит переход на Python 3:С Python <2.7:
Использование:
источник
Это точно обрабатывает классы как старого, так и нового стиля.
источник
Я смотрел на то, как Django справляется с этим
django.utils.module_loading имеет это
Вы можете использовать его как
import_string("module_path.to.all.the.way.to.your_class")
источник
Да, ты можешь это сделать. Предполагая, что ваши классы существуют в глобальном пространстве имен, что-то вроде этого сделает это:
источник
С точки зрения выполнения произвольного кода или нежелательных имен, переданных пользователем, у вас может быть список допустимых имен функций / классов, и, если входные данные соответствуют одному в списке, это eval'd.
PS: я знаю ... немного поздно ... но это для всех, кто столкнется с этим в будущем.
источник
Использование importlib работало лучше для меня.
При этом используется нотация с точкой для модуля Python, который вы хотите импортировать.
источник
Если вы действительно хотите получить классы, которые вы делаете со строкой, вы должны сохранить (или правильно сформулировать, ссылку ) их в словаре. В конце концов, это также позволит назвать ваши классы на более высоком уровне и избежать выявления нежелательных классов.
Например, из игры, в которой классы актеров определены в Python, и вы хотите избежать других общих классов, которые будут доступны при вводе пользователем.
Другой подход (как в примере ниже) состоит в создании целого нового класса, который содержит
dict
вышеупомянутое. Это будет:Пример:
Это возвращает меня:
Еще один забавный эксперимент с ними - добавить метод, который перебирает все,
ClassHolder
чтобы вы никогда не потеряли все классы, которые вы сделали: ^)источник