我从这样的事情开始:
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 还有一段时间......)