executing a function with feeding its global variables

Discussion in 'Python' started by Jean-Daniel, Feb 12, 2011.

  1. Jean-Daniel

    Jean-Daniel Guest

    Hello,

    I am writing a small framework where the user which writes a function
    can expect some global variable to be set in the function namespace.

    The user has to write a function like this:
    """
    # function.py
    from framework import, command, run

    @command
    def myfunc():
    print HOST

    if __name__=="__main__":
    run()
    """

    command() registers the function, and run() evaluates or execute the
    function within an environment or a namespace where HOST has been
    automagically set.

    Question: how can write run in a way that when using run() in a
    script, the decorated function will be run with the special names made
    available?

    Here is the code for this, which does not work as intended because the
    'HOST' can not be found when evaluating the decorated function

    """
    # framework.py
    HOST = '192.168.0.1'
    PORT = 12345

    commands = []

    def command(f):
    commands.append(f)
    return f

    def run():
    for f in commands:
    assert globals()['HOST']
    exec 'f()' in globals(),locals()

    if __name__=='__main__':

    @command
    def info():
    print HOST,PORT

    run()
    """

    Note that the assert makes sure the HOST variable is indeed present in
    the globals when running the function. When running function.py, I get
    an NameError exception. When I put the func function in the framework
    module and execute framework.py as a script, this works fine, the
    global HOST is available in the func namespace which gets printed. I
    tried many combinations of eval() or exec as well as many combinations
    for the globals() and locals() mapping fed to eval/exec without
    success.


    Thank you for your help
    Jean-Daniel, Feb 12, 2011
    #1
    1. Advertising

  2. Jean-Daniel

    Peter Otten Guest

    Jean-Daniel wrote:

    > Hello,
    >
    > I am writing a small framework where the user which writes a function
    > can expect some global variable to be set in the function namespace.
    >
    > The user has to write a function like this:
    > """
    > # function.py
    > from framework import, command, run
    >
    > @command
    > def myfunc():
    > print HOST
    >
    > if __name__=="__main__":
    > run()
    > """
    >
    > command() registers the function, and run() evaluates or execute the
    > function within an environment or a namespace where HOST has been
    > automagically set.
    >
    > Question: how can write run in a way that when using run() in a
    > script, the decorated function will be run with the special names made
    > available?
    >
    > Here is the code for this, which does not work as intended because the
    > 'HOST' can not be found when evaluating the decorated function
    >
    > """
    > # framework.py
    > HOST = '192.168.0.1'
    > PORT = 12345
    >
    > commands = []
    >
    > def command(f):
    > commands.append(f)
    > return f
    >
    > def run():
    > for f in commands:
    > assert globals()['HOST']
    > exec 'f()' in globals(),locals()
    >
    > if __name__=='__main__':
    >
    > @command
    > def info():
    > print HOST,PORT
    >
    > run()
    > """
    >
    > Note that the assert makes sure the HOST variable is indeed present in
    > the globals when running the function. When running function.py, I get
    > an NameError exception. When I put the func function in the framework
    > module and execute framework.py as a script, this works fine, the
    > global HOST is available in the func namespace which gets printed. I
    > tried many combinations of eval() or exec as well as many combinations
    > for the globals() and locals() mapping fed to eval/exec without
    > success.


    Every module has its own global namespace, and a function is looking for
    global variables in the namespace it is defined in, not the one where the
    function is called from. A function defined in Python carries its global
    namespace with it as the __globals__ attribute (func_globals in older Python
    versions).

    def run():
    for f in commands:
    f.__globals__.update(HOST=HOST, PORT=PORT)
    f()

    Note that every function in the function's module will see the extra
    variables.

    Peter
    Peter Otten, Feb 12, 2011
    #2
    1. Advertising

  3. Jean-Daniel

    Jean-Daniel Guest

    On Sat, Feb 12, 2011 at 7:25 PM, Peter Otten <> wrote:
    > Jean-Daniel wrote:
    >
    >> Hello,
    >>
    >> I am writing a small framework where the user which writes a function
    >> can expect some global variable to be set in the function namespace.
    >>
    >> The user has to write a function like this:
    >> """
    >> # function.py
    >> from framework import, command, run
    >>
    >> @command
    >> def myfunc():
    >>     print HOST
    >>
    >> if __name__=="__main__":
    >>     run()
    >> """
    >>
    >> command() registers the function, and run() evaluates or execute the
    >> function within an environment or a namespace where HOST has been
    >> automagically set.
    >>
    >> Question: how can write run in a way that when using run() in a
    >> script, the decorated function will be run with the special names made
    >> available?
    >>
    >> Here is the code for this, which does not work as intended because the
    >> 'HOST' can not be found when evaluating the decorated function
    >>
    >> """
    >> # framework.py
    >> HOST = '192.168.0.1'
    >> PORT = 12345
    >>
    >> commands = []
    >>
    >> def command(f):
    >>     commands.append(f)
    >>     return f
    >>
    >> def run():
    >>     for f in commands:
    >>         assert globals()['HOST']
    >>         exec 'f()' in globals(),locals()
    >>
    >> if __name__=='__main__':
    >>
    >>     @command
    >>     def info():
    >>         print HOST,PORT
    >>
    >>     run()
    >> """
    >>
    >> Note that the assert makes sure the HOST variable is indeed present in
    >> the globals when running the function. When running function.py, I get
    >> an NameError exception. When I put the func function in the framework
    >> module and execute framework.py as a script, this works fine, the
    >> global HOST is available in the func namespace which gets printed. I
    >> tried many combinations of eval() or exec as well as many combinations
    >> for the globals() and locals() mapping fed to eval/exec without
    >> success.

    >
    > Every module has its own global namespace, and a function is looking for
    > global variables in the namespace it is defined in, not the one where the
    > function is called from. A function defined in Python carries its global
    > namespace with it as the __globals__ attribute (func_globals in older Python
    > versions).
    >
    > def run():
    >    for f in commands:
    >        f.__globals__.update(HOST=HOST, PORT=PORT)
    >        f()
    >
    > Note that every function in the function's module will see the extra
    > variables.


    Cool, thanks.

    I read here: http://docs.python.org/reference/datamodel.html about the
    func_globals and how it is a read only attribute. I incorrectly
    thought that this dictionary was read only because the reference was
    read only.


    >
    > Peter
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
    Jean-Daniel, Feb 12, 2011
    #3
    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. Andrew Thompson
    Replies:
    1
    Views:
    395
    Mickey Segal
    Apr 2, 2004
  2. kazaam
    Replies:
    5
    Views:
    143
    kazaam
    Sep 4, 2007
  3. thunk
    Replies:
    1
    Views:
    292
    thunk
    Mar 30, 2010
  4. thunk
    Replies:
    0
    Views:
    455
    thunk
    Apr 1, 2010
  5. thunk
    Replies:
    14
    Views:
    600
    thunk
    Apr 3, 2010
Loading...

Share This Page