A story over on SmartDisorganized about the return of GeekWeaver and why my software is like Cthulhu.
"The sovereignty you have over your work will inspire far more people than the actual content ever will." - Gaping Void
Showing posts with label metaprogramming. Show all posts
Showing posts with label metaprogramming. Show all posts
Wednesday, July 31, 2013
Saturday, September 08, 2007
Maybe ... just maybe ... I'm starting to see what Python decorators are all about.
Have a look at this example :
log1 and log2 are lists representing two alternative logs
declogFactory is actually a routine which is going to return a closure which is a python decorator.
so declogFactory receives a list as an argument and returns a decorator with the variable l bound to that list.
we assign that decorator to "declog" in the main program.
but what is declog?
decorators are functions which transform other functions, and are invoked with the @ syntax before the function they transform.
So this :
is applying the new decorator "declog" to the function "add".
Let's look inside the definition of the decorator
this decorator also takes one argument : f that will be the function to be decorated.
we, in turn define function new. All it does is append the name of the function f it receives, with the first two arguments, to the log. Then it calls f.
effectively we've wrapped a call to f inside another routine which updates the log first.
however, we don't need to do this explicitly. You'll see that, although the routines add and times have been decorated, the calls to them look exactly the same as a call to a non-decorated version.
the simple occurance of the decorator line @declog before each definition is sufficient to turn each routine into a logged routine, as we see from the output
both add and times are decorated.
note, as well, that the decorator was itself parameterized with which log. it's sufficient to change the line defining the decorator to
to have the logging from all the functions redirected to log2 instead of log1
Have a look at this example :
log1 = []
log2 = []
def declogFactory(l) :
def declog(f) :
def new(*args, **kws) :
l.append((f.__name__,args[0],args[1]))
return f(*args, **kws)
return new
return declog
declog = declogFactory(log1)
@declog
def add(x,y) :
return x + y
@declog
def times(x,y) :
return x * y
print add(1,2)
print log1, log2
print times(4,5)
print log1, log2
log1 and log2 are lists representing two alternative logs
declogFactory is actually a routine which is going to return a closure which is a python decorator.
so declogFactory receives a list as an argument and returns a decorator with the variable l bound to that list.
we assign that decorator to "declog" in the main program.
but what is declog?
decorators are functions which transform other functions, and are invoked with the @ syntax before the function they transform.
So this :
@declog
def add(x,y) :
return x + y
is applying the new decorator "declog" to the function "add".
Let's look inside the definition of the decorator
def declog(f) :
def new(*args, **kws) :
l.append((f.__name__,args[0],args[1]))
return f(*args, **kws)
return new
this decorator also takes one argument : f that will be the function to be decorated.
we, in turn define function new. All it does is append the name of the function f it receives, with the first two arguments, to the log. Then it calls f.
effectively we've wrapped a call to f inside another routine which updates the log first.
however, we don't need to do this explicitly. You'll see that, although the routines add and times have been decorated, the calls to them look exactly the same as a call to a non-decorated version.
the simple occurance of the decorator line @declog before each definition is sufficient to turn each routine into a logged routine, as we see from the output
3
[('add', 1, 2)] []
20
[('add', 1, 2), ('times', 4, 5)] []
both add and times are decorated.
note, as well, that the decorator was itself parameterized with which log. it's sufficient to change the line defining the decorator to
declog = declogFactory(log2)
to have the logging from all the functions redirected to log2 instead of log1
Marcadores:
decorators,
metaprogramming,
programming,
python
Subscribe to:
Posts (Atom)
