>>> eval('potato', {'__builtins__': None})
NameError: name 'potato' is not defined
Python2。很有意义。
>>> eval('potato', {'__builtins__': None})
TypeError: 'NoneType' object is not subscriptable
Python 3. eval
如何/为什么尝试对None
下标?我希望在这里使用相同的NameError
,或者可能是AttributeError: 'NoneType' object has no attribute 'potato'
。
答案 0 :(得分:2)
来自eval(expression, globals=None, locals=None)
docs:
如果存在globals字典且缺少“
__builtins__
”,则 在解析表达式之前,将当前全局变量复制到全局变量中。 这意味着表达式通常可以完全访问标准__builtin__
模块和受限环境得以传播。
但是您正在将globals词典中的__builtins__
设置为None
,因此您的代码将求值为None['potato']
,从而导致:
TypeError: 'NoneType' object is not subscriptable
编辑:
如果Python2.7在NameError
-source code中找不到变量,则会引发__builtins__
。 NAME_ERROR_MSG
定义为:
#define NAME_ERROR_MSG \
"name '%.200s' is not defined"
Python3打印不同的消息-请参见source-PyObject_GetItem
不会引发KeyError
而是TypeError
,因此字符串的格式不同,在这种情况下为TypeError: 'NoneType' object is not subscriptable
在CPython中,名称__builtins__
可以绑定到模块或字典。那就是documented under the execution model:
与代码块的执行相关的内建命名空间实际上是通过在其全局命名空间中查找名称
__builtins__
来找到的;这应该是字典或模块(在后一种情况下,将使用模块的字典)。