decorating a memberfunction

  • Thread starter Ulrich Eckhardt
  • Start date
U

Ulrich Eckhardt

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
 
M

MRAB

Ulrich said:
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. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top