python - 从嵌入式 Python 脚本导入模块
问题描述
tl;dr 如何从嵌入式 Python 脚本中导入 Python 模块,以便导入的模块可以使用主机系统提供的全局变量和函数?
我正在为某个系统编写 Python 脚本(大概是用 C++ 编写的)。我编写脚本,将其放入一个特殊的预定义文件夹中,系统会在某些事件上执行它。
随着脚本变得庞大而笨拙,我想将其拆分为几个模块,比如说,module1.py
和module2.py
,由 导入main_script.py
,由主机系统加载和执行。但是,导入的模块不能使用全局的东西main_script.py
(我假设,主机系统在加载时添加了一些全局变量、函数、类等main_script.py
;但是,这些模块不是由主机系统直接加载的,所以它们最终不会拥有所有这些全局变量)。
到目前为止,我已经提出了以下内容 - 它查找存在于模块中main_script.py
但不存在于模块中的全局变量,并将它们添加到模块中:
#main_script.py
import module1, module2
for m in [module1, module2]:
for k, v in globals().items():
if not hasattr(m, k):
setattr(m, k, v)
它可以工作(至少对我来说到目前为止),但看起来并不特别优雅:我必须列出两次导入的模块;如果我想从模块中导入一些子模块,我必须在那里做同样的事情;我必须注意可能的全球名称冲突等)由于这个问题听起来并不少见,我觉得我可能在这里重新发明方轮。有一个更好的方法吗?
UPD.:根据@Merlin Katz 的回答和@Sraw 的评论[我的解释?] 建议,我修改了我的脚本如下。首先,添加了一个空脚本core.py
。然后修改main_script.py
:
#main_script.py
import core
#only inject into the empty 'core' module
for k, v in globals().items():
if not hasattr(core, k):
setattr(core, k, v)
#can now import modules that depend on those globals
import module1, module2
然后,必须使用注入的全局变量的每个模块都应该core
从那里导入并使用它们:
#module1.py
import core
_blah = core.blahblah #a shortcut
core.call_global_function()
my_obj1 = core.blahblah.SomeClassDefinedInBlahblah()
my_obj2 = _blah.SomeClassDefinedInBlahblah() #a bit shorter version of the above
#etc.
这看起来有点干净,并且没有覆盖某些现有全局变量的风险。由导入的模块,module1
也module2
可以简单地import core
使用全局变量。
UPD .:此外,我不确定它是否值得,但core.py
您可以动态创建它,而不是保留一个空模块:
#main_script.py
import sys
from types import ModuleType
core = ModuleType("core")
sys.modules["core"] = core
#inject into our dynamically created 'core' module
for k, v in globals().items():
if not hasattr(core, k):
setattr(core, k, v)
#the modules can still import `core` the same way as before
import module1, module2
解决方案
这应该可以解决必须列出两次模块的问题 - 您可以使用该importlib
库从变量名中导入模块
>>> import importlib
>>> np = importlib.import_module('numpy')
>>> np.pi
3.141592653589793
所以从一个列表来看
import importlib
modules = [importlib.import_module(module_name) for module_name in module_names]
for m in modules:
...
至于同步全局变量,我不想这么说,但我认为没有完美的方法可以做到这一点。我之前遇到过这个问题,我的解决方案是将我希望在每个模块中可用的每个函数或变量放入一个单独的 core.py 文件中,每个模块都从该文件中导入。除此之外,我认为您拥有的是最简单的方法,如果有其他解决方案,我很想听听。
推荐阅读
- javascript - 下一个 JS 构建不适用于撇号
- mysql - MYSQL 中多个 CASE-WHEN VS 多个 IF 语句之间的区别
- c++ - Ret 的模板 ( Class::*member )( Args... )
- vue.js - Web3js 在 Vue3 组合 api 项目中导入失败
- contactless-smartcard - 从智能卡读取数据 - pyscard
- javascript - 检查对象数组值是否为空
- javascript - 对对象数组进行深度过滤
- c# - 如何在 .NET 中获取 Linux 文件类型(常规、durector、符号链接、字符设备等)?
- gatsby - 在 Gatsby 中以编程方式创建帖子时,如何使用多个模板显示来自 Contentful API 的博客帖子
- python - Seaborn histplot 使用奇怪的 y 轴限制?