Injecting a global into a defined function??

Terry Reedy tjreedy at udel.edu
Thu Jan 15 22:16:13 CET 2009


Cong Ma wrote:

> I'd appreciate your hints on this problem. I'm writing a module in which several
> functions can alter the value of a global variable (I know this sounds evil,

Not to me.  You are using the module as a singleton class. The 
alternative is to write a class, make the functions methods, and 
instantiate the class.  If that instance must be a singleton, more work 
is required.  If multiple instances make sense, you can go the class 
route when you need to.

> please forgive me...). What I'm trying to do is to eliminate the "global foo"
> lines in those functions' bodies and to use a decorator for the same task.

This sounds foolish and senseless (but not evil ;-).

>For example:
> 
>     @global_injected("SPAM")
>     def foo():
>         ... ...
> 
> will have the same effect as
> 
>     def foo():
>         global SPAM
>         ... ...

More keystrokes for no gain.

> Leaving the evilness of globals aside, I wonder how I can implement this (for
> Python 2.x).

Decorators are usally intended to wrap the input function with another 
function.  But they can be used to modify the input function and return 
it altered.  The latter is what you are proposing.

You of course have to use SPAM as a local variable.  Then you might be 
able to write an implementation-specific convert_to_global(name) 
function that would rewrite the code part of the code object of the 
function to what it would have been had you been sensible and used the 
'global' directive.  This would mean finding the code that loads and 
stores 'SPAM' as a local variable and convert is to code that loads and 
stores it as a global variable.  If the replacement takes more bytes 
than the original, then the jump offsets all have to be fixed.  Also 
needing fixing would be the line number table that is used to match code 
units to lines in the Python code for error tracebacks.

An alterntive would be to de-compile the code, insert the global 
directive, and recompile.  A non-decorator alternative would be to write 
a function with two parameters that takes a tuple of names and the code 
quoted as a string as arguments.  It would insert the global statement 
into the string, execute it, and return the function.

> I'd like to hear your opinions. Thank you.

I hope I have convinced you to forget this idea.

Terry Jan Reedy




More information about the Python-list mailing list