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

M

mrstevegross

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!).

Is there a way to use __import__ to make this work? Any ideas?

Thanks,
--Steve
 
P

Peter Otten

mrstevegross said:
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
 
C

Carl Banks

I'm trying to import a module so that the globals() of the importer
module are available to the imported module itself. [snip]


In general, the way I recommend to deal with this issue (aside from
reorganizing your code) is to pass the function you want to call in as
an argument. Rewrite your go function like so:


def go(function_to_call):
# do stuff
function_to_call(1,2)
# do rest of stuff


Then, from the other modules, call it like this:

mymod.go(some_special_func)


What you are looking to do isn't THAT unreasonable, and there are some
libraries that are based strongly on callbacks (which is the term for
what you're trying to do). However, few if any libraries try to
determine the callback automatically; you have to explicity pass the
function/object to call back to.


Carl Banks
 
D

Dave Angel

mrstevegross said:
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!).

Is there a way to use __import__ to make this work? Any ideas?

Thanks,
--Steve
Your sample is very hard to follow, because you're mis-using the word
built-in. Built-ins are part of the Python implementation, and
available everywhere, while you apparently just mean a function visible
in foo.py, which may have been imported from somewhere else.

One solution would be that after importing mymod, you assign to its
global space, as follows:

def some_special_function():
.....
import mymod
mymod.some_special_function = some_special_function


You're adding a global name to the mymod namespace, and giving it a
reference to a function in your own space.
Note that the two names don't have to be the same in the two files. You
could use, for example:
import os
mymod.some_special_function = os.path.join
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top