Динамически загружать модуль и динамически вызывать функцию в этом модуле;Python 2.7 - PullRequest
0 голосов
/ 26 августа 2018

Я пытаюсь написать код Python 2.7, который будет

  1. Динамически загружать список / массив модулей из файла конфигурации при запуске
  2. Вызов функций из этих модулей. Эти функции также обозначены в файле конфигурации (возможно, тот же файл конфигурации, может быть, другой).

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

У меня ничего не получается. Простой пример моей ситуации такой:

Ниже приведен abc.py, модуль, который должен быть загружен динамически (в моем реальном приложении у меня было бы несколько таких модулей, обозначенных в списке / массиве в файле конфигурации):

    def abc_fcn():
        print("Hello World!")

    def another_fcn():
        print("BlahBlah")

Ниже приведен код .py, который должен загружать abc.py (мой настоящий код должен был бы импортировать весь список / массив модулей из файла конфигурации). И этот файл .py, и файл abc.py находятся в одной папке / каталоге. Пожалуйста, обратите внимание на комментарии рядом с каждым утверждением.

    module_to_import = "abc"        #<- Will normally come from config file
    fcn_to_call = "abc.abc_fcn"     #<- Will normally come from config file

    __import__(module_to_import)    #<- No error

    print(help(module_to_import))   #<- Works as expected
    eval(fcn_to_call)()             #<- NameError: name 'abc' is not defined

Когда я меняю вторую строку на следующую ...

    fcn_to_call = "abc_fcn"

... NameError изменяется на «имя 'abc_fcn' не определено».

Что я делаю не так? Заранее спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

__import__ возвращает только указанный модуль, но не добавляет его в глобальное пространство имен.Таким образом, чтобы выполнить то, что вы хотите, сохраните результат как переменную, а затем динамически получите нужную функцию.Это может выглядеть следующим образом:

fcn_to_call = 'abc_fcn'
mod = __import__(module_to_import)
func = getattr(mod, fcn_to_call)
func()

На заметке abc - это имя * встроенного модуля Python Abstract Base Classes , хотя я знаю, что вы, вероятно, просто использовали этопример.

0 голосов
/ 26 августа 2018

Вы должны присвоить возвращаемое значение __import__ переменной abc, чтобы вы могли использовать ее в качестве модуля.

abc = __import__(module_to_import)
...