transitions功能有序的轉換以及queued
轉換可能是您正在尋找。基本技巧是每當處理完相同的事件時調用相同的事件(使用finalize
)。即使轉換未成功,傳遞給finalize
的回叫也將被處理(並非所有conditions
返回True
)。使用queued
轉換不會立即處理事件,而是在當前處理的事件之後立即處理事件,這將防止大量遞歸。
from transitions import Machine
import time
class Model(object):
# initialise counter and counter limit
def __init__(self):
self.counter = 0
self.limit = 5
# will be called in every cycle and increase the counter
def increase_counter(self):
self.counter += 1
print("Counter increased to ", self.counter)
time.sleep(0.5)
# will be called whenever a new state has been entered
def reset_counter(self):
self.counter = 0
print("Counter reset; Current state is ", model.state)
# this function returns whether the limit has already been reached
def limit_reached(self):
return self.counter >= self.limit
# initialising the previously defined model
model = Model()
# creating some state names
states = ['A', 'B', 'C', 'D']
# configuring the state machine:
# pass the model (for callbacks), pass the state names,
# disable auto_transitions since we will not need them
# set the initial state to 'A' and call a (currently) undefined
# model function 'next_state' after EVERY triggered event.
# 'queued' means that every transition is finished before the next event is handled
machine = Machine(model, states=states, auto_transitions=False,
queued=True, initial='A', finalize_event='next_state')
# now add ordered transitions:
# Depending on the order of the passed state names,
# create transitions from each state 'n' to state 'n+1' called 'next_state'.
# 'prepare' each transition attempt by increasing the counter
# afterwards check the 'conditions' (is the counter limit reached)
# if all callbacks in 'conditions' return True, the transition
# is conducted and callbacks in 'after' are processed (counter reset)
machine.add_ordered_transitions(prepare='increase_counter', conditions='limit_reached',
after='reset_counter', trigger='next_state')
# model will go into an infinite loop; can be triggered in a thread
model.next_state()
你可以儘量減少睡眠定時器increase_counter
檢查是否會打一個遞歸誤差(你不應該)。如果您設置了queued=False
這是標準行爲,您將立即或多或少地發生遞歸錯誤,因爲所有計算機觸發器都將立即處理。
我可能會看看這個 –
@ user252046的協同程序遞歸的問題是什麼。你爲什麼要「沒有它」? – Rajez
我不希望程序在達到基本情況後回撥。循環永遠持續下去。我知道這可以通過調用函數的主循環來完成,但會造成一大堆混亂。 – user252046