How does the eval() function change the di

2019-06-03 19:58发布

How does eval() change the dict? This is an example: create a dict -> print -> eval -> print

>>> a={'a':'a','b':'b'}
>>> print(a)
{'a': 'a', 'b': 'b'}
>>> eval('a == "a"',a)
True
>>> print(a)
{'a': 'a', '__builtins__': {'bytearray': <class 'bytearray'>, 'IndexError': <class 'IndexError'>, 'all': <built-in function all>, 'help': Type help() for interactive help, or help(object) for help about object., 'vars': <built-in function vars>, 'SyntaxError': <class 'SyntaxError'>, 'UnicodeDecodeError': <class 'UnicodeDecodeError'>, 'memoryview': <class 'memoryview'>, 'isinstance': <built-in function isinstance>, '__build_class__': <built-in function __build_class__>, 'copyright': Copyright (c) 2001-2012 Python Software Foundation.
All Rights Reserved.
...

3条回答
贪生不怕死
2楼-- · 2019-06-03 20:21

Yes it does. The second argument to eval() is the "globals" dictionary, which explains what you're seeing.

查看更多
不美不萌又怎样
3楼-- · 2019-06-03 20:30

The answer resides in the doc !

First of all, the second parameter to eval is the global dictionary. Than, we see:

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

So yes, your dictionary gets modified by the call to eval.

查看更多
狗以群分
4楼-- · 2019-06-03 20:36

The second argument to eval() is the globals used for the expression run by eval().

One of things python does when evaluating an expression is ensuring that the python built-ins are available to the evaluated expression, and to do that it adds the __builtins__ entry to that globals namespace.

So, yes, the eval() call did change your dictionary, and that is expected and normal behaviour. It even says so in the documentation for the function:

If the globals dictionary is present and lacks ‘__builtins__’, the current globals are copied into globals before expression is parsed. This means that expression normally has full access to the standard __builtin__ module and restricted environments are propagated.

If you want to avoid this change, use an empty dict for the globals, and use a as the locals namespace instead:

eval('a == "a"', {}, a)
查看更多
登录 后发表回答