# -*- coding: utf-8 -*-
# Author: João S. O. Bueno
# License: Creative Commons Attribution 3.0
# http://creativecommons.org/licenses/by/3.0/
from inspect import currentframe
from types import FunctionType
def caller_variables(func):
"""A decorator that makes the local variables on the caller function
available as Free Variables on the called function.
Creates the possibility for differente ways of thinking about scope
when coding
Warning: Decoration order matters for this decorator: it should be the outermost one
Until introspection allows one to find out our way in decorated functions
(expected for Python 3.2)
"""
def new_func(*args, **kw):
caller_vars = currentframe(1).f_locals
#now, recreate the decorated function as a new function,
# so that it has the local variables from the caller
# scope as its global variables:
new_globals = func.func_globals.copy()
new_globals.update(caller_vars)
# and recreate the called functions, updating only the global dict
# so that variables from the calling scope apear to be global variables
# to it.
reforged_func = FunctionType(func.func_code, new_globals, func.func_name,
func.func_defaults, func.func_closure)
return reforged_func(*args, **kw)
return new_func
if __name__ == "__main__":
##
## test
##
self = "this should not be printed"
@caller_variables
def a():
print self
def b():
self = "This should be printed."
a()
b()
class C(object):
def __init__(self):
a()
def __repr__(self):
return "And this as well."
c = C()