python - exec 函数:在类定义中导入未知数
问题描述
我想使用 Python 文件来配置程序。这些文件将通过exec
. 部分配置是类定义:
配置文件
import collections as col # module alias does not matter
a = col.defaultdict() # works as expected
class Foo:
b = col.defaultdict() # causes NameError: name 'col' is not defined
主文件
CONFIG = {}
with open('config.py') as f:
exec(f.read(), None, CONFIG)
现在,在运行main.py时,我会遇到一个问题,即在类定义之外导入的模块是已知的,但在它内部却不是。为什么以及是否有解决方法?
解决方案
根据exec 的文档,
如果 exec 获得两个单独的对象作为全局对象和局部对象,则代码将被执行,就好像它嵌入在类定义中一样。
所以你的 config.py 代码相当于
class SomeClass:
import collections as col
a = col.defaultdict()
class Foo:
b = col.defaultdict()
这是一个问题,因为根据名称解析,
类块中定义的名称范围仅限于类块[.]
col
在隐式的类块中定义SomeClass
。此变量的范围仅限于该类块;即使该块内的块,例如class Foo:
,也无法访问它。
一种可能的解决方案是为 和 传递相同的对象globals
,locals
这样您的代码就不会像嵌入到类定义中一样被执行。
exec(f.read(), CONFIG, CONFIG)
推荐阅读
- javascript - reject() 和 return 不会终止执行
- python - 如何避免分页Flask中随机显示的元素?
- reactjs - 检查用户是否在会话期间访问过路线
- perl - 连接来自“keytool -list”输出的证书行
- java - 鉴于 List 是 JRL 的一部分,为什么 javac 不能访问 List
- python - (2003,“无法连接到 'localhost' 上的 MySQL 服务器([Errno 2] 没有这样的文件或目录)
- android-emulator - QEMU 无头,通过 VNC 的 GUI
- c# - html菜单覆盖另一个下拉菜单
- firebase - 更改当前实时数据库位置
- docker - 如何在docker模式下更改bitbucket-server的上下文路径