Decorator Dissection

Ron_Adam radam2 at tampabay.rr.com
Sat Apr 2 13:39:41 EST 2005


On Sat, 02 Apr 2005 19:59:30 +0200, "Diez B. Roggisch"
<deetsNOSPAM at web.de> wrote:

>> statements documenting the flow in a few minutes.  I'm still a bit
>> fuzzy on how the arguments are stored and passed.
>
>The arguments are part of the outer scope of the function returned, and thus
>they ar kept around. That's standart python,too:
>
>def foo():
>    a = 10
>    def bar():
>       return a*a
>    return bar
>
>print foo()()
>
>
>No decorator-specific magic here - just references kept to outer frames
>which form the scope for the inner function.

I followed that part.  The part that I'm having problems with is the
first nested function get's the argument for the function name without
a previous reference to the argument name in the outer frames. So, a
function call to it is being made with the function name as the
argument, and that isn't visable so it looks as if it's magic.

Ok, Since I was using the wrong model the first time, probably due to
not sleeping well and mixing past language experience in improperly,
we will try again.

In the below model, the @decorator, (object or the interpreter
executing the @decorator statement?), calls nested functions in the
function of the same name until it reaches the inner loop which is
then attached to the function name. Is this correct now?

Cheers,
Ron


### Decorator Dissection V.2 ###

print "\n(0) Start reading decorator defs"
def decorator(d_arg):
    print "(3) decorator: gets '"+d_arg+"'"
    
    def get_function(function):
        print "(6) get_function: gets 'func' object"
        
        def wrapper(f_arg): 
            print "(10) wrapper: gets '"+f_arg+"'"
            new_arg = f_arg+'-'+d_arg

            print "(11) wrapper: calls func('"+new_arg+"')"
            result = function(new_arg)
                                        
            print "(13) wrapper: returns '"+result+"'"
            return result

        print "(7) get_function: returns 'wrapper' object"
        return wrapper

    w = get_function 
    print "(4) decorator: return 'get_function' object"
    print '(5) @decorator: calls get_function(func)'
            # Need to print this here, done at *(5)
    return w
                            
print "(1) Done reading decorator defs\n"


print "(2) @decorator: calls decorator('goodbye')"
            # *(5) @decorator: call get_funtion(func)
@decorator('Goodbye')
def func(s):
    print '(12) func returns:', s
    return s
print "(8) @decorator: func = wrapper\n"


print "(9) Call func('Hello') which is now wrapper object:"
result = func('Hello')
print "(14) result gets '"+result+"'\n"

print result                        


#---output---

(0) Start reading decorator defs
(1) Done reading decorator defs

(2) @decorator: calls decorator('Goodbye')
(3) decorator: gets 'Goodbye'
(4) decorator: return 'get_function' object
(5) @decorator: calls get_function(func)
(6) get_function: gets 'func' object
(7) get_function: returns 'wrapper' object
(8) @decorator: func = wrapper

(9) Call func('Hello') which is now wrapper object:
(10) wrapper: gets 'Hello'
(11) wrapper: calls func('Hello-Goodbye')
(12) func returns: Hello-Goodbye
(13) wrapper: returns 'Hello-Goodbye'
(14) result gets 'Hello-Goodbye'

Hello-Goodbye





More information about the Python-list mailing list