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

Discussion in 'Python' started by mrstevegross, Apr 9, 2009.

  1. mrstevegross

    mrstevegross Guest

    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
     
    mrstevegross, Apr 9, 2009
    #1
    1. Advertising

  2. mrstevegross

    Peter Otten Guest

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

    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
     
    Peter Otten, Apr 9, 2009
    #2
    1. Advertising

  3. mrstevegross

    Carl Banks Guest

    Re: How to import a module so that the current globals are availableto the module?

    On Apr 9, 2:25 pm, mrstevegross <> wrote:
    > 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
     
    Carl Banks, Apr 9, 2009
    #3
  4. mrstevegross

    Dave Angel Guest

    Re: How to import a module so that the current globals are availableto the module?

    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!).
    >
    > 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
     
    Dave Angel, Apr 10, 2009
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ron_Adam
    Replies:
    2
    Views:
    262
    Ron_Adam
    Mar 29, 2005
  2. Matt Winward
    Replies:
    0
    Views:
    537
    Matt Winward
    Mar 20, 2008
  3. Weng Tianxiang
    Replies:
    7
    Views:
    1,293
    Paul Uiterlinden
    Sep 11, 2009
  4. Stephan Steiner
    Replies:
    1
    Views:
    356
    bruce barker
    Sep 24, 2009
  5. George Weis
    Replies:
    2
    Views:
    1,335
    John B. Matthews
    Feb 23, 2010
Loading...

Share This Page