Use eval with dictionary without losing imported modules in Python2
<p>I have a string to be executed inside my python program and I want to change some variables in the string like x[1], x[2] to something else.
I had previously used eval with 2 arguments (the second being a dict with replaced_word: new_word) but now I noticed I can't use previously imported modules like this. So if I do this</p>

<pre><code>from math import log
eval(log(x[1], {x[1]: 1})
</code></pre>

<p>it will say it doesn't recognize the name log.
How can I use eval like this without losing the global variables?
I can't really make sense of the documentation:
<a href="https://docs.python.org/2/library/functions.html#eval" rel="nofollow">https://docs.python.org/2/library/functions.html#eval</a>
so an explanation would be useful too.</p>

<p>Build your globals <code>dict</code> with <a href="https://docs.python.org/2/library/functions.html#globals" rel="nofollow"><code>globals()</code></a> as a base:</p>

<pre><code>from math import log

# Copy the globals() dict so changes don't affect real globals
eval_globals = globals().copy()
# Tweak the copy to add desired new global
eval_globals[x[1]] = 1

# eval using the updated copy
eval('log(x[1])', eval_globals)
</code></pre>

<p>Alternatively, you can use <a href="https://docs.python.org/2/library/functions.html#eval" rel="nofollow">three-arg <code>eval</code></a> to use <code>globals()</code> unmodified, but also supply a <code>local</code>s <code>dict</code> that will be checked (and modified) first, in preference to global values:</p>

<pre><code>eval('log(x[1])', globals(), {x[1]: 1})
</code></pre>

<p>In theory, the latter approach could allow the expression to mutate the original globals, so adding <code>.copy()</code> to make it <code>eval('log(x[1])', globals().copy(), {x[1]: 1})</code> minimizes the risk of that happening accidentally. But pathological/malicious code could work around that; <code>eval</code> is dangerous after all, don't trust it for arbitrary inputs no matter how sandboxed you make it.</p>

python eval python-2.x