Why aren't globals copied when I run eval with a globals argument?

瘦欲@ 提交于 2019-12-10 19:03:29

问题


I'm having difficulty understanding how eval() behaves regarding the globals used in the evaluated expression.

For example, the following script prints 1:

x = 1
print eval('x')

While the following script fails on NameError: name 'x' is not defined:

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

However, from the documentation of eval() for my Python version (emphasis mine):

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. If the globals dictionary is present and lacks ‘__builtins__’, the current globals are copied into globals before expression is parsed.

So according to this, since a globals argument is present and indeed lacks __builtins__, I'd expect all the current globals - including x - to be copied into it before the expression is evaluated; but apparently that is not the case. What am I missing?


回答1:


This appears to be a bug. Whether it's a bug in the documentation or the implementation, I don't know, but eval does not copy the current globals into globals if __builtins__ is not present. Rather, it only copies __builtins__:

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

I didn't find anything about this on the Python bug tracker, and the discrepancy is still present in 3.4 and the current dev branch, so it may be worth submitting a bug report and a proposed documentation correction:

If the globals dictionary is present and lacks ‘__builtins__’, the current __builtins__ is copied into globals before expression is parsed.



来源:https://stackoverflow.com/questions/24934908/why-arent-globals-copied-when-i-run-eval-with-a-globals-argument

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!