2017-08-25 58 views
-3

我想从一个状态切换到另一个状态。每个状态都由一个函数表示。我想处理在函数内部切换的逻辑,而不是调用该函数的主循环。是否有一个Python库允许这种模式。 因此,例如:是否有一个python库,让你调用函数内的函数,但不会创建递归堆栈

def c(count): 
    if count<10: 
     a(count+1) 
     print("dont' keep track of post-order printing") 
    else: 
     print("when count is reached, program should terminate") 
def b(count): 
    c(count): 
def a(count): 
    b(count) 
a() 

这只是一个例子,我试图用一个有限状态图案,其中的逻辑是on_enter方法的过渡中。基本上,机器会自动从一个状态转换到下一个状态,而不使用main_loop。

+0

我可能会看看这个 –

+0

@ user252046的协同程序递归的问题是什么。你为什么要“没有它”? – Rajez

+0

我不希望程序在达到基本情况后回拨。循环永远持续下去。我知道这可以通过调用函数的主循环来完成,但会造成一大堆混乱。 – user252046

回答

0

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这是标准行为,您将立即或多或少地发生递归错误,因为所有计算机触发器都将立即处理。

+0

这个完美的作品! – user252046

0

我希望它可能它可能适合你的期望

def c(count): 
    if count<10: 
     print("don't keep track of post-order printing") 
     c(count+1) 
    else: 
     print("when count is reached, program should terminate") 

输出:

>>> c(1) 
don't keep track of post-order printing 
don't keep track of post-order printing 
don't keep track of post-order printing 
don't keep track of post-order printing 
don't keep track of post-order printing 
don't keep track of post-order printing 
don't keep track of post-order printing 
don't keep track of post-order printing 
don't keep track of post-order printing 
when count is reached, program should terminate