简而言之,由于eval用于动态求值,解释器无法知道它应该将a添加到{}的局部作用域中。为了提高效率,解释器不会向局部变量的dict添加不需要的变量。在
来自^{}的文档:The expression argument is parsed and evaluated as a Python expression (technically speaking, a condition list) using the globals and locals dictionaries as global and local namespace.
这意味着函数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)
实际上,由于解释器在解析g的主体时没有看到对a的引用,因此它不会将其添加到其局部变量中。在
要使其工作,您需要在g中指定nonlocal a。在
输出
^{pr2}$
在第二个示例中,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