python - 为什么 eval 找不到在外部函数中定义的变量?

标签 python eval local-variables

我知道 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

在您的第二个示例中,ag 局部变量中,因为它在作用域中使用。

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/

相关文章:

c++ - 当同名的全局和局部变量已经存在时如何访问变量(c++)?

python - 从关键字列表中查找所有句子到字典

python - 如何将 Pandas 中的特定列拆分为新列?

python - Pytz 上的错误 - IndexError : list index out of range

Javascript - eval() `{}` 表达式

namespaces - 如何在 ClojureScript 中运行 eval 并访问调用 eval 的命名空间?

javascript - 使用局部变量(而不是重复的属性访问)是否会损害性能?

python - 我可以在windows上使用python中的android模块吗

Python:加快重复执行的 eval 语句的方法?

c - C 中的临时变量和局部变量有什么区别?