2 回答
TA贡献2019条经验 获得超9个赞
简而言之,由于eval是动态评估,解释器无法知道它应该添加a到g. 为了效率,解释器不会将不需要的变量添加到dict局部变量中。
来自文档eval:
表达式参数被解析和评估为 Python 表达式(从技术上讲,条件列表),使用 globals 和 locals 字典作为全局和本地命名空间。
这意味着这些函数eval(expression)将globals()用作其默认全局范围,locals()如果没有提供,则用作其局部范围。
虽然,在你的第一个例子a中都不是。
def f(a):
print("f's locals:", locals())
def g():
print("g's locals:", locals())
print(eval('a'))
return g()
f(1)
实际上,由于解释器a在解析 的主体时看不到对 的引用g,因此不会将其添加到其局部变量中。
要使其正常工作,您需要nonlocal a在g.
输出
f's locals: {'a': 1}
g's locals: {}
Traceback ...
...
NameError: name 'a' is not defined
在您的第二个示例中,a在g局部变量中,因为它在作用域中使用。
def f(a):
print("f's locals:", locals())
def g():
print("g's locals:", locals())
b = a + 1
print("g's locals after b = a + 1:", locals())
print(eval('a'))
return g()
f(1)
输出
f's locals: {'a': 1}
g's locals: {'a': 1}
g's locals after b = a + 1: {'a': 1, 'b': 2}
1
TA贡献1802条经验 获得超6个赞
看起来 eval() 只能在 local(here,g) 或 global 中查找变量,而不能在其父环境(此处为 f)中查找变量。四处走走是将变量设置为全局。
定义 f(a): global b #注意,不能直接使用"global a",会报错:"name 'a' is parameter and global" b=a 定义 g(): 打印(评估('b')) 返回 g()f(1)
输出:1
添加回答
举报