动态加载模块并在该模块中动态调用函数; Python 2.7

时间:2018-08-26 11:47:48

标签: python-2.7 dynamic eval

我正在尝试编写将使用的Python 2.7代码

  1. 启动时从配置文件中动态加载模块列表/模块
  2. 从那些模块中调用函数。这些功能也在配置文件中指定(可能是相同的配置文件,也可能是不同的配置文件)。

这个想法是我的代码直到启动要加载的模块才知道。直到运行时,调用函数的部分才知道要调用哪些函数以及这些函数属于哪些模块。

我没有成功。我的情况的一个简单示例是:

以下是abc.py,该模块应动态加载(在我的实际应用程序中,我将在配置文件的列表/数组中指定多个这样的模块):

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

    def another_fcn():
        print("BlahBlah")

以下是应加载abc.py的.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 :(得分:1)

__import__仅返回指定的模块,不会将其添加到全局名称空间。因此,要完成所需的操作,请将结果另存为变量,然后动态检索所需的函数。看起来像

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

在旁注中,abcAbstract Base Classes builtin Python module的名称,尽管我知道您可能只是在使用此示例。

答案 1 :(得分:0)

您应该将__import__的返回值分配给变量abc,以便可以将其实际用作模块。

abc = __import__(module_to_import)