Reputation: 11
Okay I'm trying to do something with python version 3.3.2 I'm trying to import module so I don't have to restart the shell. The following is just an example the final code will be able to change:
def importing():
x = compile('import sys',"<string","exec")
exec(x)
return True
The problem with this is when I call on this using test.importing()
it returns True but when i do sys it says:
Traceback (most recent call last):
File "<pyshell#74>", line 1, in <module>
sys
NameError: name 'sys' is not defined
Whats confusing me is though it works perfectly fine in the shell, any ideas or advice would be very thankful to me.
Upvotes: 1
Views: 414
Reputation: 8620
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__
.
Upvotes: 1
Reputation: 6757
If you want to dynamically import modules you can use __import__
.
Example Dive into Python:
>>> sys = __import__('sys')
>>> os = __import__('os')
>>> re = __import__('re')
>>> unittest = __import__('unittest')
>>> sys
>>> <module 'sys' (built-in)>
>>> os
>>> <module 'os' from '/usr/local/lib/python2.2/os.pyc'>
Upvotes: 2
Reputation: 2925
if you just want to reload a module, you can do
from imp import reload
reload(sys)
Upvotes: 2