I started out with something like this:
class Client (object):
def __init__ (self):
self.state = None
def open (self, destination):
if self.state not in [None]: raise error ...
... open stuff ...
self.state = 'Open'
def handle (self):
if self.state not in ['Open'] raise error ...
... handle stuff ...
def close (self):
if self.state not in ['Open'] raise error ...
... close stuff ...
self.state = None
(I'm not happy about having separate __init__()
and open()
methods but the stuff I call requires things to be this way, I'm afraid. It's not central to my question anyhow.)
Now, as the number of methods and states will be growing, I thought I should refactor into something like this:
@states([None])
def open (self, destination):
... open stuff ...
and similarly for the other methods. Based on e.g. this classic SO answer I came up with the following definition for the decorator:
from functools import wraps
def states (statelist):
def decorator (f):
@wraps(f) # In order to preserve docstrings, etc.
def wrapped (self, *args, **kwargs):
if self.state not in statelist: raise error ...
return f(self, *args, **kwargs)
return wrapped
return decorator
This is fairly complex, and also has the problem that it will not be inherited by derived classes (my solution was to simply make it a global). My question is: is this the minimal, idiomatic solution to this problem, or am I doing something wrong? This is the first time I'm trying to define my own decorator. The various references I have found (including this one which pointed me to wraps
) seem to suggest to my uninformed self that this is really how it has to be. (Or is there a nifty library which encapsulates this sort of contortion for me? Had a quick glance at functools
but I can't say I understand the documentation really, and anyway, the nifty stuff seems to be >= 2.6 whereas I need to support Python 2.5 for a little while still ...)