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

Python 2.7 动态加载模块并动态调用该模块中的函数;Python 2.7,python-2.7,dynamic,eval,Python 2.7,Dynamic,Eval,我正在尝试编写Python 2.7代码,它将 启动时从配置文件动态加载模块列表/阵列 从这些模块调用函数。这些函数也在配置文件中指定(可能是相同的配置文件,也可能是不同的配置文件) 我的想法是,在启动之前,我的代码不知道要加载哪些模块。调用函数的部分直到运行时才知道要调用哪些函数以及这些函数属于哪些模块 我没有成功。我的情况的一个简单例子是: 下面是abc.py,一个应该动态加载的模块(在我的实际应用程序中,我会在配置文件的列表/数组中指定几个这样的模块): 下面是加载abc.py的.py代码(

我正在尝试编写Python 2.7代码,它将

  • 启动时从配置文件动态加载模块列表/阵列
  • 从这些模块调用函数。这些函数也在配置文件中指定(可能是相同的配置文件,也可能是不同的配置文件)
  • 我的想法是,在启动之前,我的代码不知道要加载哪些模块。调用函数的部分直到运行时才知道要调用哪些函数以及这些函数属于哪些模块

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

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

    下面是加载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
    
    …名称错误更改为“未定义名称‘abc_fcn’”


    我做错了什么?提前感谢您的帮助

    您应该将
    \uuuuu import\uuuu
    的返回值分配给变量
    abc
    ,以便实际将其用作模块

    abc = __import__(module_to_import)
    

    \uuuuu import\uuuu
    仅返回指定的模块,而不将其添加到全局命名空间。因此,要实现您想要的功能,请将结果保存为变量,然后动态检索您想要的函数。看起来像

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

    另一方面,
    abc
    是的名称,尽管我知道您可能只是在使用这个示例。

    谢谢您的建议。我将“\uuuu import\uuuu(module\u to\u import)”更改为您建议的函数,但出现了相同的错误。我尝试对代码的其余部分进行相应的更改,但我不确定这些更改会是什么。我应该提到的一件事是,实际代码需要动态导入配置文件中定义的模块列表/数组,而不仅仅是一个。我将编辑原始帖子来说明这一点。好的,我现在明白了。谢谢你的帮助!你说得对:这只是一个例子。我确实想过按照你的建议使用getattr。问题是我的代码会导入几个模块并调用几个函数,而不知道哪个模块拥有哪个函数。如果fcn_to_调用是“abc.abc_fcn”,那么我的代码必须在“.”上拆分,以获得模块名和函数名。我肯定能做到,但这似乎是多余的工作。当我以交互方式使用python时,我可以输入“importabc”,然后输入“eval('abc.abc_fcn')()”,它完全按照预期工作。我遗漏了什么?因为正如我所提到的,
    \uuuu import\uuuu
    函数与
    import
    关键字不同,它不会在全局名称空间中对模块提出质疑。如果您想这样做,请编写
    abc=\uuuu导入('abc')
    ,然后是
    global abc
    .Aah。知道了。令人惊叹的!谢谢你的帮助!很抱歉,但我刚刚意识到这并不能解决我的问题。我意识到我的问题不完整,于是编辑了它。问题是在启动时会导入一个模块列表,因此使用您的建议“mod”将是一个列表;i、 模块[0]是一个模块,模块[1]是另一个模块,依此类推。稍后需要调用该函数。根据您的建议,“func”如何知道使用列表mod中的哪个元素?我猜mod可以是一个以模块名为键的字典。这是最好的办法吗?再次感谢!马修和布莱辛的建议让我大吃一惊。此外,我还需要以下内容:(a)将模块列表存储在配置文件中(b)让应用程序在启动时加载这些模块(c)将所有模块分配给一个Dict,其中键为模块名称(d)让应用程序在“.”上拆分一个函数字符串(例如“abc.abc_fcn”),以获得列表(e)使用列表中的第一个元素作为键来查找前面提到的Dict中的模块(f)call getattr(mod,LIST[1])();列表[1](列表中的第二个元素)是函数(例如“fcn_abc”)。到目前为止,我还不知道更干净的方法。
    abc = __import__(module_to_import)
    
    fcn_to_call = 'abc_fcn'
    mod = __import__(module_to_import)
    func = getattr(mod, fcn_to_call)
    func()