decorating a memberfunction

MRAB python at mrabarnett.plus.com
Wed Jun 2 12:39:49 EDT 2010


Ulrich Eckhardt wrote:
> Hi!
> 
> I have a class that maintains a network connection, which can be used to
> query and trigger Things(tm). Apart from "normal" errors, a broken network
> connection and a protocol violation from the peer are something we can't
> recover from without creating a new connection, so those errors
> should "stick".
> 
> The code looks roughly like this:
> 
> class Client(object):
>     def __init__(self, ...):
>         self._error = None
> 
>     def _check(fn):
>         def do_check(self, *args, **kwargs):
>             # check for sticky error
>             if self._error:
>                 raise self._error
> 
>             try:
>                 fn(self, *args, **kwargs)
>             except NetworkError, e:
>                 self._error = e
>                 raise
>             except ProtocolError, e:
>                 self._error = e
>                 raise
>         return do_check
> 
>     @_check
>     def frobnicate(self, foo):
>         # format and send request, read and parse answer
> 
> So, any function like frobnicate() that does things is decorated with
> _check() so that unrecoverable errors stick. I hope I didn't shorten the
> code too much to understand the principle, in particular I'm using
> functools.wraps() in order to retain function names and docstrings.
> 
> 
> Is this sound? Would you have done it differently? Any other suggestions?
> What I'm mostly unsure about is whether the definition of _check() and
> do_check() are correct or could be improved.
> 
You could merge the two excepts:

             try:
                 fn(self, *args, **kwargs)
             except (NetworkError, ProtocolError), e:
                 self._error = e
                 raise

You could also choose a better name for the decorator, eg
_check_sticky_error. :-)



More information about the Python-list mailing list