当我使用globals参数运行eval时,为什么不复制全局变量?

时间:2014-07-24 13:20:30

标签: python eval

我很难理解eval()在评估表达式中使用的全局变量的行为方式。

例如,以下脚本打印1

x = 1
print eval('x')

以下脚本在NameError: name 'x' is not defined上失败:

x = 1
print eval('x', {})

然而,从the documentation of eval() for my Python version(强调我的):

  

表达式参数使用 globals locals 字典作为Python表达式(技术上讲,条件列表)进行解析和评估。全局和本地命名空间。 如果 globals 字典存在且缺少'__builtins__',则在解析表达式之前将当前全局变量复制到 globals

所以根据这个,由于 globals 参数存在且确实缺少__builtins__,我希望所有当前的全局变量 - 包括x - 都是在评估表达式之前将其复制到其中;但显然事实并非如此。我错过了什么?

1 个答案:

答案 0 :(得分:4)

这似乎是一个错误。无论是文档中的错误还是实现中的错误,我都不知道,但eval如果globals不存在,则不会将当前全局变量复制到__builtins__。相反,it only copies __builtins__

if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
    if (PyDict_SetItemString(globals, "__builtins__",
                             PyEval_GetBuiltins()) != 0)
        return NULL;
}

我在Python bug tracker上没有找到任何关于此内容的信息,并且差异仍然存在于3.4和当前的开发分支中,因此可能值得提交错误报告和建议的文档更正:

  

如果 globals 字典存在且缺少“__builtins__”,则在表达式<之前将当前__builtins__复制到 globals 中/ em>被解析。