Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中通过相对脚本动态导入变量_Python_Python Import - Fatal编程技术网

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

在Python中通过相对脚本动态导入变量,python,python-import,Python,Python Import,在我的主要Python脚本中,调用了一个web API。该调用的结果确定需要运行什么“协议”。这些协议是名为protocols/的子文件夹中的单个python脚本 那么,在我的主脚本中,如何动态调用其中一个脚本?脚本名称是来自API的变量,它位于主脚本的子文件夹中,而不是标准库位置 我可以使用subprocess.popen或os.system,但我希望一切尽可能留在内部 必须有一种方法在一个Python实例中实现这一点,对吗?有一个Python内置函数可以处理调用脚本 该文件名为execfil

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

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

我可以使用subprocess.popen或os.system,但我希望一切尽可能留在内部


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

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

该文件名为execfile,您可以通过以下网址了解更多信息:

如果我有一个名为testmeagain.py的文件,其中包含以下内容:

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

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

假设您从将协议视为子文件夹的目录中运行主Python程序,则应将空的uuu init_uuuuuu.py添加到协议目录中,使其成为一个包

然后,您应该能够从那里导入特定于协议的模块,例如

from protocols.http import process_it
在这里,我假设您将有一个名为process_it的函数

还有其他方法,如本SO答案中所述,如何导入在变量中定义名称的包

在您的情况下,它会以某种方式看起来像:

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

是的,可以在一个Python实例中实现这一点。可以按以下方式动态加载单个python脚本:

仅使用importlib.import\u模块动态加载模块 使用getattr动态加载模块和类。 备选案文1 如果只想动态加载模块,请使用importlib.import\u模块。假设子文件夹协议中有以下协议: 包含以下类别的协议/协议_1.py:

class Protocol():
    # some protocol specific code
class Protocol():
    # some protocol specific code
class Protocol_1():
    # some protocol specific code
class Protocol_2():
    # some protocol specific code
包含以下类别的协议/协议_2.py:

class Protocol():
    # some protocol specific code
class Protocol():
    # some protocol specific code
class Protocol_1():
    # some protocol specific code
class Protocol_2():
    # some protocol specific code
首先,我们使用将从Web API返回的协议名称定义动态变量:

module = 'protocols.protocol_1' 
module = 'protocols.protocol_1' 
class_name = 'Protocol_1'
然后导入importlib并动态加载模块。协议类在两个文件中具有相同的类名,但具有特定于协议的代码。之后,我们用动态加载的协议实例化api_协议:

import importlib

Protocol = importlib.import_module(module).Protocol

api_protocol = Protocol()
mod = __import__(module, fromlist=[class_name])
Protocol = getattr(mod, class_name)
api_protocol = Protocol()
备选案文2 如果还希望动态加载类,请使用getattr。假设子文件夹协议中有以下协议:

包含以下类别的协议/协议_1.py:

class Protocol():
    # some protocol specific code
class Protocol():
    # some protocol specific code
class Protocol_1():
    # some protocol specific code
class Protocol_2():
    # some protocol specific code
包含以下类别的协议/协议_2.py:

class Protocol():
    # some protocol specific code
class Protocol():
    # some protocol specific code
class Protocol_1():
    # some protocol specific code
class Protocol_2():
    # some protocol specific code
首先,我们使用将从Web API返回的协议名称定义动态变量:

module = 'protocols.protocol_1' 
module = 'protocols.protocol_1' 
class_name = 'Protocol_1'
然后我们调用_import _函数来动态加载动态模块的类。之后,我们可以使用getattr创建新类,并使用动态加载的协议实例化api_协议:

import importlib

Protocol = importlib.import_module(module).Protocol

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