通过变量动态导入Python中的相对脚本

时间:2014-04-30 21:03:22

标签: python variables import relative

在我的主Python脚本中,调用了一个Web API。该调用的结果决定了“协议”需要运行的内容。这些协议是名为protocols/的子文件夹中的单个python脚本。

因此,从我的主脚本中,如何动态调用其中一个脚本?脚本名称是来自API的变量,它位于主脚本的子文件夹中 - 而不是标准库位置。

我可以使用subprocess.popenos.system,但我希望所有内容都尽可能保留在内部。

在一个Python实例中必须有一种方法可以实现这一点,对吗?

3 个答案:

答案 0 :(得分:0)

有一个Python内置函数可以处理调用脚本。

它被称为execfile,你可以在以下网站了解更多信息:

https://docs.python.org/2/library/functions.html#execfile

如果我有一个名为testmeagain.py的文件,其内容为:

print "test print"

您可以在不导入其他库的情况下执行此操作:

In [1]: execfile("testmeagain.py")
test print

答案 1 :(得分:0)

假设您从目录中运行主Python程序,该目录将protocols视为子文件夹,您应将空__init__.py添加到protocols目录中以使其成为包。

然后你就可以从那里导入你的协议特定模块,例如

from protocols.http import process_it

在这里,我假设你会有一些名为process_it

的函数

还有其他方法,如何导入包含在变量中定义的名称的包,如在这个SO答案中enter link description here

在你的情况下,它看起来像是:

def process_it(protocol="http"):
    mod = __import__("protocols." + protocol)
    mod.process_it()

答案 2 :(得分:0)

是的,有可能在一个Python实例中完成此任务。可以动态加载各个python脚本,如下所示:

  1. 使用importlib.import_module()
  2. 动态加载模块
  3. 使用getattr()动态加载模块和类。
  4. 备选方案1

    如果您只想动态加载模块,请使用importlib.import_module()。假设您在子文件夹协议中有以下协议:

    protocols / protocol_1.py 包含以下类:

    class Protocol():
        # some protocol specific code
    

    protocols / protocol_2.py 包含以下类:

    class Protocol():
        # some protocol specific code
    

    首先,我们使用将从Web API返回的协议名称定义动态变量:

    module = 'protocols.protocol_1' 
    

    然后我们导入importlib并动态加载模块。 Protocol类在两个文件中都有相同的类名,但协议特定的代码。然后,我们使用动态加载的协议实例化api_protocol:

    import importlib
    
    Protocol = importlib.import_module(module).Protocol
    
    api_protocol = Protocol()
    

    备选方案2

    如果您还想动态加载类,请使用getattr。假设您在子文件夹协议中有以下协议:

    protocols / protocol_1.py 包含以下类:

    class Protocol_1():
        # some protocol specific code
    

    protocols / protocol_2.py 包含以下类:

    class Protocol_2():
        # some protocol specific code
    

    首先,我们使用将从Web API返回的协议名称定义动态变量:

    module = 'protocols.protocol_1' 
    class_name = 'Protocol_1'
    

    然后我们调用__import__函数以动态加载动态模块。之后我们可以使用getattr创建新类,并使用动态加载的协议实例化api_protocol:

    mod = __import__(module, fromlist=[class_name])
    Protocol = getattr(mod, class_name)
    api_protocol = Protocol()