How to add function return value

George Sakkis george.sakkis at gmail.com
Sat May 31 10:40:15 EDT 2008


On May 30, 10:16 pm, Raymond Hettinger <pyt... at rcn.com> wrote:
> On May 30, 6:21 pm, HYRY <ruoyu0... at gmail.com> wrote:
>
> > Can I write a decorator that it can automately do this conversion
>
> > def func1()
> >     a = 1
>
> > --->
>
> > def func1():
> >     a = 1
> >     return locals()
>
> Not sure why you would want to do this, but there are several ways.
>
> 1. Make bytecode hack decorator that transforms the final "return
> None" into "return locals()".  A recipe that shows the basic technique
> is at:http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/277940
>
> 2. Retrieve the source using inspect.getsourcelines(f). Then, append a
> "return locals()" to the end of the function and run it through exec.
>
> 3. Try hacking a tracing/debugging utility.
>
> 4. Run the sourcefile through tokenize, make the appropriate
> insertion, and then untokenize.


Here's an illustration of (3):

import sys
import functools

def withlocals(f):
    @functools.wraps(f)
    def wrapper(*args, **kwds):
        f_locals = {}
        def probe(frame, event, arg):
            if event == 'return':
                f_locals.update(frame.f_locals)
            return probe
        sys.settrace(probe)
        try: res = f(*args,**kwds)
        finally: sys.settrace(None)
        return (res, f_locals)
    return wrapper

# example

@withlocals
def foo(x, y=0, *args, **kwds):
    a = max(x,y)
    b = len(args)
    c = min(kwds.values())
    return a+b+c

r,locs = foo(1,2,3,4,a=5,b=6)
print locs

George



More information about the Python-list mailing list