我知道 eval()
的使用通常意味着错误的代码,但我偶然发现内部函数中的 eval()
函数有一个奇怪的行为,我无法理解。如果我们写:
def f(a):
def g():
print(eval('a'))
return g()
在这种情况下运行 f(1)
会产生一个 NameError
,声称 a
没有定义。但是,如果我们定义
def f(a):
def g():
b = a + 1
print(eval('a'))
return g()
然后运行 f(1)
打印 1
。
局部变量和全局变量发生了一些我不太理解的事情。 a
只是 g()
中的一个局部变量,当它被“用于”某事时?这是怎么回事?
最佳答案
简而言之,由于 eval
用于动态评估,解释器无法知道它应该将 a
添加到 g
的本地范围>。为了效率,解释器不会将不需要的变量添加到局部变量的dict
中。
来自 eval
的文档:
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
。
输出
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
关于python - 为什么 eval 找不到在外部函数中定义的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52298505/