首页 > 解决方案 > 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时,我会遇到一个问题,即在类定义之外导入的模块是已知的,但在它内部却不是。为什么以及是否有解决方法?

标签: pythonpython-3.xevalpython-import

解决方案


根据exec 的文档

如果 exec 获得两个单独的对象作为全局对象和局部对象,则代码将被执行,就好像它嵌入在类定义中一样。

所以你的 config.py 代码相当于

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

这是一个问题,因为根据名称解析

类块中定义的名称范围仅限于类块[.]

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

一种可能的解决方案是为 和 传递相同的对象globalslocals这样您的代码就不会像嵌入到类定义中一样被执行。

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

推荐阅读