exec 函数:在 class 定义中导入未知

exec function: import unknown in class definition

我想使用 Python 个文件来配置程序。文件将通过 exec 读取。部分配置是 class 定义:

config.py

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

main.py

CONFIG = {}

with open('config.py') as f:
    exec(f.read(), None, CONFIG)

现在,当 运行 main.py 我会遇到一个问题,即在 class 定义之外导入的模块是已知的,但是里面不是。为什么以及是否有解决方法?

根据exec's documentation,

If exec gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition.

所以你的config.py代码等同于

class SomeClass:
    import collections as col
    a = col.defaultdict()
    class Foo:
        b = col.defaultdict()

这是一个问题,因为根据 Resolution of Names

The scope of names defined in a class block is limited to the class block[.]

col 是在隐式 SomeClass 的 class 块中定义的。该变量的范围仅限于 class 块;即使是该块内的块,例如 class Foo:,也无法访问它。

一个可能的解决方案是为 globalslocals 传递相同的对象,这样您的代码就不会像嵌入在class定义。

exec(f.read(), CONFIG, CONFIG)