decorator question

Bengt Richter bokr at oz.net
Sun Jan 8 23:20:58 CET 2006


On Sun, 08 Jan 2006 23:26:28 +0100, =?ISO-8859-1?Q?Sch=FCle_Daniel?= <uval at rz.uni-karlsruhe.de> wrote:
[...]
>
>the code above works fine
>but I am wondering wheather it's possible to
>write something like this
>
> >>> def timelogger(f, logfile=sys.stdout):
>...     def wrapper(*a,**kw):
>...             logfile.write("started at %s" % time.ctime())
>...             t0 = time.time()
>...             f(*a, **kw)
>...             t1 = time.time()
>...             logfile.write("ended at %s" % time.ctime())
>...             logfile.write("diff = %f %s" % (t1-t0, "sec"))
>...     return wrapper
>
> >>> import time
> >>> @timelogger(file("hierher", "a"))	### <<<<<< (1)
>... def loops(a,b,c):
>...     sum = 0
>...     for i in range(a):
>...             for j in range(b):
>...                     for k in range(c):
>...                             sum += 1
>...
>
>(1) fails to compile
>is it possible to pass parameters to a decorator function?
>
Yes, but then the function must return the same kind of thing
a bare decorator-function name would have, which is a function
able to take a single argument of a function and return a function.

So your decorator won't take f as an argument, just the optional logfile,
and it will return a function that does the wrapping like the original decorator.

 >>> import sys, time
 >>> def timelogger(logfile=sys.stdout):
 ...    def deco(f):
 ...        def wrapper(*a,**kw):
 ...                logfile.write("started at %s\n" % time.ctime())
 ...                t0 = time.time()
 ...                f(*a, **kw)
 ...                t1 = time.time()
 ...                logfile.write("ended at %s\n" % time.ctime())
 ...                logfile.write("diff = %f %s\n" % (t1-t0, "sec"))
 ...        return wrapper
 ...    return deco
 ...
 >>> @timelogger() # stdout
 ... def foo(): pass
 ...
 >>> foo()
 started at Sun Jan 08 14:13:55 2006
 ended at Sun Jan 08 14:13:55 2006
 diff = 0.000000 sec
 >>> foo()
 started at Sun Jan 08 14:14:02 2006
 ended at Sun Jan 08 14:14:02 2006
 diff = 0.000000 sec
 >>> @timelogger() # stdout
 ... def foo(dt): time.sleep(dt)
 ...
 >>> foo(5)
 started at Sun Jan 08 14:14:59 2006
 ended at Sun Jan 08 14:15:04 2006
 diff = 5.007000 sec
 >>> foo(.5)
 started at Sun Jan 08 14:15:16 2006
 ended at Sun Jan 08 14:15:17 2006
 diff = 0.501000 sec
 >>>
 
Regards,
Bengt Richter



More information about the Python-list mailing list