miscoranda: by Sean B. Palmer

Python Method Meta-Decorators

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...

by Sean B. Palmer, at 2005-03-23 17:01:17. Comment?

Eph · emano

Sean B. Palmer