有,虽然你必须写它。一种可能性是创建一个descriptor,做基于instance.state
或任何选择的state_attr
调度:
class StateDispatcher(object):
def __init__(self, state_attr='state'):
self.registry = {}
self._state_attr = state_attr
def __get__(self, instance, owner):
if instance is None:
return self
method = self.registry[getattr(instance, self._state_attr)]
return method.__get__(instance, owner)
def register(self, state):
def decorator(method):
self.registry[state] = method
return method
return decorator
https://docs.python.org/3/howto/descriptor.html#functions-and-methods:
为了支持方法调用,函数包括用于属性访问期间结合方法__get__()
方法。这意味着所有函数都是非数据描述符,它们返回绑定或未绑定的方法,具体取决于它们是从对象还是类调用。
在有状态类,你可以创建一个调度员和注册方法:
class StateMachine(object):
dispatcher = StateDispatcher()
state = None
@dispatcher.register('test')
def test(self):
print('Hello, World!', self.state)
@dispatcher.register('working')
def do_work(self):
print('Working hard, or hardly working?', self.state)
让我们来看看它在行动:
>>> sm = StateMachine()
>>> sm.state = 'test'
>>> sm.dispatcher()
Hello, World! test
>>> sm.state = 'working'
>>> sm.dispatcher()
Working hard, or hardly working? working
>>> sm.state = None
>>> sm.dispatcher()
Traceback (most recent call last):
...
File "dispatcher.py", line 11, in __get__
method = self.registry[getattr(instance, self._state_attr)]
KeyError: None
请注意,这是调度的一个非常邪恶的方法基于状态,因为对于未来的代码读者来说,整个机制将很难遵循。
调度文本状态的另一种方法是在方法名称中对状态进行编码,并根据调度函数中的选择正确的方法。很多python类都使用这种模式(例如ast.NodeVisitor
):
class StateMachine(object):
def dispatch(self, *args, **kwgs):
getattr(self, 'do_{}'.format(self.state))(*args, **kwgs)
def do_new(self):
print('new')
def do_archive(self):
print('archive')
sm = StateMachine()
sm.state = 'new'
sm.dispatch()
sm.state = 'archive'
sm.dispatch()
非常感谢您的支持。我真的不得不学习这个'描述符'魔术 –