From: Ulrich Eckhardt on 2 Jun 2010 11:37 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. Thanks! Uli -- Sator Laser GmbH Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
From: MRAB on 2 Jun 2010 12:39 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. :-)
|
Pages: 1 Prev: Properly posting links (was Re: Python Forum) Next: Simple hack to get $500 to your home. |