decorators question

Duncan Booth duncan.booth at invalid.invalid
Tue Dec 5 03:42:49 EST 2006


"king kikapu" <aboudouvas at panafonet.gr> wrote:

> Hmmm...ok...it calls the decorator but when ?? It (the runtime) loads
> the .py file and start to call every decorator
> it finds on it, regardless of the existance of code that actually calls
> the decorated functions ??
> I understand thet Python does not call the decoratated functiond but it
> ends up this way...

Try this code to help you understand what is going on:

----------- t.py ----------------
import inspect

def adecorator(f):
    print "decorating", f.__name__, inspect.getargspec(f)
    return f

def makeargument(n):
    print "makeargument", n, "called"
    return n

print "for loop coming up"
for i in range(3):
    print "in for loop, iteration", i
    @adecorator
    def fn(x=makeargument(i)):
        print "fn called, x=", x
    print "end of iteration", i

print "now call fn"
fn()
print "done"
---------------------------------

Run it and the output shows you clearly when each element executes.

Note in particular that the def statement inside the loop executes every 
time through the loop and each time it creates a new function (which 
differs only in the default argument value), the default argument is 
evaluated when the def executes, NOT when the function is called.
The decorator is called after the def executes and before the next 
statement.
At the end of the for loop we are left only with the last definition of fn: 
the others are overwritten during the loop.

The output looks like this:

C:\temp>t.py
for loop coming up
in for loop, iteration 0
makeargument 0 called
decorating fn (['x'], None, None, (0,))
end of iteration 0
in for loop, iteration 1
makeargument 1 called
decorating fn (['x'], None, None, (1,))
end of iteration 1
in for loop, iteration 2
makeargument 2 called
decorating fn (['x'], None, None, (2,))
end of iteration 2
now call fn
fn called, x= 2
done



More information about the Python-list mailing list