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