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.
...

回答1:

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)


回答2:

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.



回答3:

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