Python 制造;“国家”;在过渡fsm包中“更多”;“有状态的”;
我正在使用一个非常有用的用于python的FSM工具。我想让美国更,嗯,有状态。。。因此,变量可以是状态的局部变量,并且在输入或离开状态时,它们的值会发生变化。我最终在机器中得到了相当多的实例变量——我真的希望这些值中的一些在状态中(例如,我在这种状态中呆了多久)。它们不是模型的属性,而是状态进展的属性 我想知道是否有“最好的方法”可以做到这一点?亚类状态Python 制造;“国家”;在过渡fsm包中“更多”;“有状态的”;,python,transitions,Python,Transitions,我正在使用一个非常有用的用于python的FSM工具。我想让美国更,嗯,有状态。。。因此,变量可以是状态的局部变量,并且在输入或离开状态时,它们的值会发生变化。我最终在机器中得到了相当多的实例变量——我真的希望这些值中的一些在状态中(例如,我在这种状态中呆了多久)。它们不是模型的属性,而是状态进展的属性 我想知道是否有“最好的方法”可以做到这一点?亚类状态 谢谢我不知道什么是“最佳方法”,但合理的方法取决于你想要实现什么。您可以a)子类状态、b)装饰初始化状态或c)手动初始化(子类)状态并将其传
谢谢我不知道什么是“最佳方法”,但合理的方法取决于你想要实现什么。您可以a)子类状态、b)装饰初始化状态或c)手动初始化(子类)状态并将其传递给机器 A)如果每个状态都具有相同的属性,则可以按照建议对状态进行子类化:
import transitions.extensions.nesting as nesting
class CounterState(nesting.NestedState):
def __init__(self, *args, **kwargs):
super(CounterState, self).__init__(*args, **kwargs)
self.entered = self.exited = 0
def enter(self, event_data):
self.entered += 1
def exit(self, event_data):
self.exited += 1
def __str__(self):
return "State {0} has been entered {1} times and exited {2} times".format(self.name, self.entered, self.exited)
class CounterMachine(nesting.HierarchicalMachine):
@staticmethod
def _create_state(*args, **kwargs):
return CounterState(*args, **kwargs)
machine = CounterMachine(states=['A', 'B'], initial='A')
a = machine.get_state('A')
b = machine.get_state('B')
print(a) # >>> State A has been entered 0 times and exited 0 times
machine.to_B()
print(a) # >>> State A has been entered 0 times and exited 1 times
print(b) # >>> State B has been entered 1 times and exited 0 times
我在这里使用了NestedMachine
,因为\u create\u state
到目前为止在Machine
中不可用更新:从版本0.4.4
开始,它也可用于机器
B)另一种方法涉及通过模型对启动状态对象进行一些修饰:
from transitions import Machine
class Model(object):
def __init__(self):
self.machine = Machine(model=self, states=['A', 'B'], initial='A',
before_state_change='exit_state',
after_state_change='enter_state')
# loop through all the states and attach attributes
for state in self.machine.states.values():
state.entered = 0
state.exited = 0
def enter_state(self):
# retrieve the state object by name
self.machine.get_state(self.state).entered += 1
def exit_state(self):
self.machine.get_state(self.state).exited += 1
def print_state(state):
print("State {0} has been entered {1} times and exited {2} times".format(state.name, state.entered, state.exited))
m = Model()
a = m.machine.get_state('A')
b = m.machine.get_state('B')
print_state(a)
m.to_B()
print_state(a)
print_state(b)
C)在必须单独处理每个状态的情况下,您可以手动启动状态,并将实例传递给计算机,而不是传递名称:
from transitions import Machine, State
class TicketState(State):
def __init__(self, name, tickets):
super(TicketState, self).__init__(name)
self.tickets = tickets
class Model(object):
def __init__(self):
# Using our own state
a = TicketState('A', 10)
# Setting tickets ourselves
b = State('B')
b.tickets = 3
self.machine = Machine(self, states=[a, b], initial='A',
before_state_change='decrease_tickets')
def tickets_left(self):
return self.machine.get_state(self.state).tickets > 0
def decrease_tickets(self):
s = self.machine.get_state(self.state)
s.tickets -= 1
if s.tickets < 0:
raise Exception('No Tickets left!')
print("State {0} has {1} tickets left.".format(s.name, s.tickets))
m = Model()
m.to_B() # >>> State A has 9 tickets left.
m.to_A() # >>> State B has 2 tickets left.
从导入计算机,状态
类别票证状态(状态):
定义初始(自我、姓名、票证):
超级(票证状态,自我)。\uuuuu初始化\uuuuuuu(名称)
self.tickets=票
类模型(对象):
定义初始化(自):
#利用我们自己的国家
a=票证状态('a',10)
#自己订票
b=状态('b')
b、 门票=3张
self.machine=machine(self,states=[a,b],initial='a',
_state_change='reduce_tickets'之前)
def票据左(自身):
返回self.machine.get_状态(self.state).tickets>0
def减少_票据(自身):
s=self.machine.get_状态(self.state)
s、 门票-=1张
如果s.tickets<0:
引发异常(“没有票证了!”)
打印(“州{0}还有{1}张票证。”.format(s.name,s.tickets))
m=模型()
m、 到B()#>>>州A还有9张票。
m、 到_A()#>>>州B还有两张票。
当然,属性和名称的数量在这里可能有所不同。除了在状态更改之前使用机器回调
,您还可以在进入/退出时将回调传递到状态
对象,以便在转换期间单独处理每个状态。或者子类State。如果您只需要一组不同的状态类型,如TimedState
和/或CounterState
则输入(self,event_data)
,这不是状态局部变量的常见解释。您所建议的是持久的变量:当您进入一个状态时,它仍然具有与上次相同的变量。通常,您将变量放入一个状态,以确保每次输入状态时它们都会被重新初始化,而此解决方案不会这样做。我不确定这是否是OP想要的,但我想我应该发表评论,因为这个建议完全把我引入了错误的道路。@DanHule:说得好。在转换中,状态实例是持久的。OP声明了“……当状态被输入或离开时,它们的值发生了变化。”这(可能是错误的)对我来说意味着这些不是范围/时间属性。对于本地/临时/作用域状态可能会有所帮助。您可以传递一个类或类路径,该类或类路径将用于在每次输入状态时初始化对象。