How to import a module so that the current globals are available to the module?

Peter Otten __peter__ at web.de
Thu Apr 9 18:20:04 EDT 2009


mrstevegross wrote:

> I'm trying to import a module so that the globals() of the importer
> module are available to the imported module itself. Consider the
> following scenario:
> 
> === mymod.py ===
> def go():
>   some_special_function(1,2)
>   # 'some_special_function' is a built-in function available in the
> scope of foo.py (see below)
> 
> === foo.py ===
> some_special_function(3,4) # 'some_special_function' is a built-in
> function
> import mymod
> mymod.go()
> === EOF ===
> 
> The problem is this: in foo.py, you can call 'some_special_function'
> all you want, because it's builtin. You can even 'print globals()' to
> verify that it is available.
> 
> However, when mymod.py tries to invoke 'some_special_function', it
> fails because the function is NOT available in that scope.
> 
> So, the question is: how can I make builtin functions available in the
> test.py scope available to the mymod.py scope?
> 
> One awkward solution is to deliberately initialize mymod.py ilke so:
> 
> === mymod.py ===
> globs=None
> def initialize(globs_): globs = globs_
> def go():
>   globs['some_special_function'] (1,2)
> 
> === foo.py ===
> some_special_function(3,4) # 'some_special_function' is a built-in
> function
> import mymod
> mymod.initialize(globals())
> mymod.go()
> === EOF ===
> 
> That will work, but it's a bit ugly. Plus, I have to repeat it for
> every module with the same problem (of which I have many!).

Have you considered what happens in an application that uses two of these
modules? Whatever is imported last wins with its idea of "some special
function".
 
> Is there a way to use __import__ to make this work? Any ideas?

Please, no. Make it explicit even if it's a bit more verbose:

--- mymod.py ---
def go(special_func):
    special_func(1, 2)

--- foo.py ---
import mymod

def some_special_func(a, b):
    print "%s * %s = %s" % (a, b, a*b)

mymod.go(some_special_func)

You can also create a shortcut for the latter:

from functools import partial
foogo = partial(mymod.go, some_special_func)
foogo()

Finally, there is an alternative that is really unclean:

--- mymod.py ---
def go():
    sys._getframe(1).f_globals["some_special_funct"](1, 2)

Peter



More information about the Python-list mailing list