Importing modules

Dave Angel davea at ieee.org
Fri Mar 19 13:25:15 CET 2010



Peyman Askari wrote:
> I want to write a function which imports modules the first time, and reloads them afterwards, but I am running into problems with global variables and exec. I will include a full script, but let me elaborate first.
>
> Essentially what you need is
>
> def import_or_reload():
>  """assume we want to load or reload sys"""
>  if 'sys' in dir():
>   reload(sys)
> else: 
>   import sys
>
> but this runs into the problem that sys is imported within the local scope of the function, so you insert a global statement
>
>
>
> def import_or_reload2():
>
>  """Add 'global sys'"""
>  global sys
>
>  if 'sys' in dir():
>
>   reload(sys)
>
> else: 
>
>   import sys
>
> 'sys' is still not in dir() as dir() pertains to the local scope of the function, but one can get around this by creating a local modules list and adding the imported modules to it
>
>
>
>
>
> def import_or_reload3():
>
>
>  """Add 'global modules'"""
>
>  global sys
>  global modules
>
>
>
>  if 'sys' in modules:
>
>
>   reload(sys)
>
>
> else: 
>
>
>   import sys
>   modules.append('sys')
>
> now lets add a parameter to the function signature, so any module name can be passed as an argument and loaded
>
>
>
>
>
> def import_or_reload4(module_name):
>
>
>
>  """Add exec"""
>  
>
> exec 'global %s'%module_name
>
>  global modules
>
>
>
>
>
>  if module_name in modules:
>
>
>
>   exec 'reload(%s)'%module_name
>
>
>
> else: 
>
>
>
>   exec 'import %s'%module_name
>
>   exec 'modules.append(\'%s\')'%module_name
>
> but this doesn't work as global does not cooperate with exec
> is there a __reload__('X') function like there is an __import__(‘X’) function? 
>
> Also is there a better way to import modules at run time?
>
> Cheers and here is the test script in case you can't access the attachment
>
> def a():
>     global modules
>     global sys
>     import sys
>
>     modules.append('sys')
>
> def b():
>     global modules
>     global sys
>
>     reload(sys)
>
> def c(module_name):
>     global modules
>     exec 'global %s'%module_name
>     exec 'import %s'%module_name
>
>     modules.append(module_name)
>
> def test():
>     global modules
>     global sys
>
>     #create the module list to contain all the modules
>     modules=[]
>
>     print 'originally dir() returns:'
>     print dir()
>
>     a()
>     print 'function a() properly imports the following module:'
>     print sys
>     print 'is %s in %s->%s'%('sys',modules,'sys' in modules)
>     
>     b()
>     print 'function b() properly reloads the following module:'
>     print sys
>     print 'is %s still in %s->%s'%('sys',modules,'sys' in modules)
>
>     try:
>         c('os')
>         print 'function c() properly imports the following module:'
>     except:
>         print 'function c() failed to import module os'
>         print 'is %s in %s->%s'%('os',modules,'os' in modules)
>
>     try:
>         print os
>         print 'is %s still in %s->%s'%('os',modules,'os' in modules)
>     except:
>         print 'os was loaded, but is not visible outside of the scope of c()'
> --- On Fri, 3/19/10, python-list-request at python.org <python-list-request at python.org> wrote:
>
> From: python-list-request at python.org <python-list-request at python.org>
> Subject: Python-list Digest, Vol 78, Issue 192
> To: python-list at python.org
> Received: Friday, March 19, 2010, 7:05 AM
>
> <snip>
(When starting a new thread, create a new message addressed to   
python-list at python.org, do not just reply to an existing message, (or 
digest, which you did here).  Some people actually try to follow 
threads, and the software to do that uses more information than just the 
message subject)

First comment.  I would seriously try to avoid using reload() in 
production code.  The problems that can result are subtle.  I use it for 
debugging sessions, but not in real programs.

But I'll assume you have a use case (which would have been good to 
explain), and have rejected the other possibilities.

Next, I'll point out that reloading sys isn't desirable, and it's one of 
the specifically proscribed modules for reloading.  But probably you 
weren't really using sys, you were just sanitizing the code since you 
knew we all had sys.

Next, if your reason for reloading is that you just changed the module 
programmatically, and it might have been loaded by some other module (as 
sys is, for example, long before your code starts), then you're not 
checking in the right place.  Instead of looking at your own global 
space, you should be looking at sys.modules to decide whether something 
has been loaded.

Perhaps the function you're looking for is imp.load_module()

DaveA




More information about the Python-list mailing list