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