Динамический импорт модуля и создание экземпляра класса в Python - PullRequest
2 голосов
/ 24 августа 2011

Мой вопрос похож на этот , хотя я бы хотел пойти дальше.

Я анализирую файл конфигурации, который вызываетколичество действий (с параметрами) по имени.Например:

"on_click": "action1", "args": {"rate": 1.5} 

Действия - это классы Python, унаследованные от базового Action класса, и могут принимать именованные аргументы.Они хранятся в подкаталоге действий проекта с префиксом a_.Я хотел бы иметь возможность добавлять новые действия, просто добавив туда новый файл, без необходимости изменения каких-либо других файлов.Структура проекта выглядит следующим образом:

myapp/
    actions/
        __init__.py
        baseaction.py
        a_pretty.py
        a_ugly.py
        ...
    run.py

Все классы действий предоставляют метод PerformAction() и метод GetName(), к которым относится файл конфигурации.В этом примере a_pretty.py определяет класс с именем PrettyPrinter.Вызов GetName() on PrettyPrinter возвращает "action1".

Я хотел бы добавить класс PrettyPrinter в словарь с ключом "action1", чтобы я мог создавать новые экземпляры этого типа, напримерследующее:

args = {'rate': the_rate}
instantiated_action = actions['action1'](**args)
instantiated_action.PerformAction()

В настоящее время у меня есть следующее:

actions = [os.path.splitext(f)[0] for f in os.listdir("actions")
           if f.startswith("a_") and f.endswith(".py")]

for a in actions:

    try:
        module = __import__("actions.%s" % a, globals(), locals(), fromlist=["*"])
        # What goes here?
    except ImportError:
        pass

Это импорт файла действия, и если я печатаю dir(module), я вижу имена классов;Я просто не знаю, что мне делать дальше (или если весь этот подход - правильный путь ...).

1 Ответ

2 голосов
/ 24 августа 2011

Если в вашем module есть все классы, которые вы должны создать, попробуйте что-то вроде этого:

для действий in:

try:
    module = __import__("actions.%s" % a, globals(), locals(), fromlist=["*"])
    # What goes here?
    # let's try to grab and instanciate objects
    for item_name in dir(module):
        try:
           new_action = getattr(module, item_name)()
           # here we have a new_action that is the instanciated class, do what you want with ;)
        except:
           pass

except ImportError:
    pass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...