Decorators in Python allow you to do something similar to class inheritance but for functions. One of the most common decorator idioms you'll come across is that of wrapping a function to provide some functionality such as trapping exceptions, or type checking the arguments; so common, in fact, that I wrote recently about a decorator for it which I've termed a meta-decorator.
The meta-decorator I wrote before only worked for functions, however, not methods. So you couldn't do calls to self, which is quite a pain sometimes. If you're wanting to trap exceptions, for example, in a class you might want to call an error(...) method that makes an appropriate callback. To that end, I've modified the original decorfunc meta-decorator to produce one that will work for methods:
def decormethod(decorator):
def wrapper(method):
return (lambda self, *args:
decorator(self, method, *args))
return wrapper
This is all a bit abstract, but hopefully the following example will make it very clear how it can be used to good effect:
class Blargh(object):
@decormethod
def safenise(self, func, *args):
try: func(self, *args)
except Exception, e: self.error(e)
def error(self, e):
print 'E: %s' % e
@safenise
def barf(self):
print 1/0
To give the simple explanation again, it's like the barf
method is inheriting from the safenise method: so any time it's
called if there's an error a call will be made to self.error, as
it will be any time barf is called since 1/0 can't be done in
Python:
>>> b = Blargh() >>> b.barf() E: integer division or modulo by zero >>>
So just like the function meta-decorator, the decormethod
modifies the argument structure, but to receive self, func,
*args, so that you can make calls to self.
If only the decorator syntax were a little clearer, this might be easier to write about...