首页 > 解决方案 > 在“exec”函数之后,locals() 中无法访问的变量

问题描述

我有一个 python 文件“test.py”,里面有代码:

    variable = 10

打开python3并输入下一个代码:

    def main():
        with open("test.py") as f:
            exec(f.read())
        print(locals())
        print(variable)
    main()

并获得输出:

{'f': <_io.BufferedReader name='test.py'>, 'variable': 10}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in main
NameError: name 'variable' is not defined

为什么 locals() 有“变量”,但不能执行它?

标签: python-3.x

解决方案


好的。这是我的解释。如果您将使用 dis 模块,您将看到以下内容:

 32 LOAD_GLOBAL              3 (print)
 34 LOAD_GLOBAL              4 (variable)
 36 CALL_FUNCTION            1

LOAD_GLOBAL - 将名为 co_names[namei] 的全局加载到堆栈上。

但是为什么 python 不尝试首先在本地命名空间中搜索呢?我认为这是由于 python 优化。如果完成:

print(main.__code__.co_varnames)
print(main.__code__.co_names)

可以看到:

('f',)
('open', 'exec', 'read', 'print', 'variable')

这样是解释器在编译时转换成字节码,看到本地范围内没有这样的变量并生成代码来搜索全局范围。但同时,变量本身的值取自局部变量和全局变量,并exec准确更新局部变量范围,为variable


推荐阅读