私はこのようなものから始めました:
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
__init__()
(別のメソッドを持つことに満足していませんopen()
が、私が呼び出すものはこのようにする必要があります.とにかく、それは私の質問の中心ではありません.)
現在、メソッドと状態の数が増えているため、次のようにリファクタリングする必要があると考えました。
@states([None])
def open (self, destination):
... open stuff ...
他の方法についても同様です。たとえば、この古典的な SO の回答に基づいて、デコレータの次の定義を思いつきました。
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
これはかなり複雑で、派生クラスに継承されないという問題もあります (私の解決策は単純にグローバルにすることでした)。私の質問は次のとおりです。これは、この問題に対する最小限の慣用的な解決策ですか、それとも何か間違ったことをしていますか? 独自のデコレータを定義しようとするのはこれが初めてです。私が見つけたさまざまな参考文献 (これを私に指摘したものwraps
を含む) は、これが実際にどうあるべきかを知らない自分に示唆しているようです. (または、この種のゆがみをカプセル化する気の利いたライブラリがありますか?ざっと見ましfunctools
たが、ドキュメントを本当に理解しているとは言えません。とにかく、気の利いたものは> = 2.6のようですが、サポートする必要がありますまだしばらくPython 2.5 ...)