The following executes without an error in Python 3:
code = """
import math
def func(x):
return math.sin(x)
func(10)
"""
_globals = {}
exec(code, _globals)
But if I try to capture the local variable dict as well, it fails with a NameError
:
>>> _globals, _locals = {}, {}
>>> exec(code, _globals, _locals)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-9-aeda81bf0af1> in <module>()
----> 1 exec(code, {}, {})
<string> in <module>()
<string> in func(x)
NameError: name 'math' is not defined
Why is this happening, and how can I execute this code while capturing both global and local variables?
From the
exec()
documentation:You passed in two separate dictionaries, but tried to execute code that requires module-scope globals to be available.
import math
in a class would produce a local scope attribute, and the function you create won't be able to access that as class scope names are not considered for function closures.See Naming and binding in the Python execution model reference:
You can reproduce the error by trying to execute the code in a class definition:
Just pass in one dictionary.