以下代码片段按预期工作:
def test():
print(f'local symbol table before exec : {locals()}')
exec('a = 0')
print(f'local symbol table after exec : {locals()}')
test()
# printed result:
# local symbol table before exec : {}
# local symbol table after exec : {'a': 0}
但是,一旦我添加了符号定义语句 a = 1
在 test
结尾函数,似乎 exec
语句对本地符号表没有影响:def test():
print(f'local symbol table before exec : {locals()}')
exec('a = 0')
print(f'local symbol table after exec : {locals()}')
a = 1
test()
# printed result:
# local symbol table before exec : {}
# local symbol table after exec : {}
那么,为什么会这样呢? 这是我的猜测:在函数内部静态定义的符号将在编译时以某种方式保留,如果符号已经保留,则在 exec 函数内部动态调用的任何符号定义语句都无法修改本地符号表。
真的吗?在编译期间实际发生了什么?
额外测试 1 : 用
'a = 0\nprint(locals())'
替换 exec 参数def test():
print(f'local symbol table before exec : {locals()}')
exec('a = 0\nprint(locals())')
print(f'local symbol table after exec : {locals()}')
test()
# printed result:
# local symbol table before exec : {}
# {'a': 0}
# local symbol table after exec : {'a': 0}
def test():
print(f'local symbol table before exec : {locals()}')
exec('a = 0\nprint(locals())')
print(f'local symbol table after exec : {locals()}')
a = 1
test()
# printed result:
# local symbol table before exec : {}
# {'a': 0}
# local symbol table after exec : {}
如我们所见,符号a
在 exec()
期间已成功添加到本地符号表中执行,但之后随着 a = 1
的存在神奇地消失了.额外测试 2 :添加
return
a = 1
之前的声明def test():
print(f'local symbol table before exec : {locals()}')
exec('a = 0\nprint(locals())')
print(f'local symbol table after exec : {locals()}')
return
test()
# printed result:
# local symbol table before exec : {}
# {'a': 0}
# local symbol table after exec : {'a': 0}
def test():
print(f'local symbol table before exec : {locals()}')
exec('a = 0\nprint(locals())')
print(f'local symbol table after exec : {locals()}')
return
a = 1
test()
# printed result:
# local symbol table before exec : {}
# {'a': 0}
# local symbol table after exec : {}
a = 1
在第二个 test()
中无法访问功能,但它仍然影响 exec()
的行为.甚至
dis()
函数来自 dis
模块无法区分这两个 test()
职能。输出完全相同,如下所示: 5 0 LOAD_GLOBAL 0 (print)
2 LOAD_CONST 1 ('local symbol table before exec : ')
4 LOAD_GLOBAL 1 (locals)
6 CALL_FUNCTION 0
8 FORMAT_VALUE 0
10 BUILD_STRING 2
12 CALL_FUNCTION 1
14 POP_TOP
6 16 LOAD_GLOBAL 2 (exec)
18 LOAD_CONST 2 ('a = 0\nprint(locals())')
20 CALL_FUNCTION 1
22 POP_TOP
7 24 LOAD_GLOBAL 0 (print)
26 LOAD_CONST 3 ('local symbol table after exec : ')
28 LOAD_GLOBAL 1 (locals)
30 CALL_FUNCTION 0
32 FORMAT_VALUE 0
34 BUILD_STRING 2
36 CALL_FUNCTION 1
38 POP_TOP
8 40 LOAD_CONST 0 (None)
42 RETURN_VALUE
最佳答案
根据documentation :
Note: The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. Pass an explicit locals dictionary if you need to see effects of the code on locals after function exec() returns.
所以我相信这属于“意外行为”,但我想你可以去执行
exec()
真正深入并理解。
关于python - 为什么 exec() 中的符号定义语句有时对本地符号表没有影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67642662/