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-requ...@python.org 
<python-list-requ...@python.org> wrote:

From: python-list-requ...@python.org <python-list-requ...@python.org>
Subject: Python-list Digest, Vol 78, Issue 192
To: python-list@python.org
Received: Friday, March 19, 2010, 7:05 AM

<snip>
(When starting a new thread, create a new message addressed to python-list@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

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to