在我的主Python脚本中,调用了一个Web API。该调用的结果决定了“协议”需要运行的内容。这些协议是名为protocols/
的子文件夹中的单个python脚本。
因此,从我的主脚本中,如何动态调用其中一个脚本?脚本名称是来自API的变量,它位于主脚本的子文件夹中 - 而不是标准库位置。
我可以使用subprocess.popen
或os.system
,但我希望所有内容都尽可能保留在内部。
在一个Python实例中必须有一种方法可以实现这一点,对吗?
答案 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脚本,如下所示:
importlib.import_module()
getattr()
动态加载模块和类。如果您只想动态加载模块,请使用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()
如果您还想动态加载类,请使用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()