exec
if no locals
and globals
passed, it executes in the current scope. So, your import sys
import the sys
module in the importing
scope. See the code:
>>> def c():
... exec('import sys')
... print(locals())
... print(globals())
...
>>> c()
{'sys': <module 'sys' (built-in)>}
{'__builtins__': <module 'builtins'>, '__package__': None, '__name__': '__main__', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, 'c': <function c at 0x7faa068e0320>, 'b': <function b at 0x7faa068e45f0>, 'a': <function a at 0x7faa066abe60>, 'd': <function d at 0x7faa068f6200>, 'inspect': <module 'inspect' from '/usr/lib64/python3.3/inspect.py'>, '__doc__': None}
See, the sys
is in the local scope but not the global scope. But note, the import is excuted dynamically, even if it is in the local scope, you can not call the sys directly in the function. The call will end up with an error, can not find the sys in the global scope:
>>> def a():
... exec('import sys')
... if sys:
... return True
... else:
... return False
...
>>> a()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in a
NameError: global name 'sys' is not defined
Instead, you should use locals()
:
>>> def b():
... exec('import sys')
... if locals()['sys']:
... return True
... else:
... return False
...
>>> b()
True
Last, I think using exec
is not a good choice. Just like others have mentioned, using __importing__
.