Есть ли библиотека python, которая позволяет вызывать функцию внутри функции wtihout при создании рекурсивного стека

-8

Я пытаюсь перейти из одного состояния в другое. Каждое состояние представлено функцией. Я хотел бы обработать логику переключения внутри функции вместо основного цикла, который вызывает функцию. Есть ли библиотека 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.

спросил(а) 2021-01-19T16:30:53+03:00 2 месяца, 3 недели назад
1
Решение
61

переходы имеют упорядоченные переходы, а также переходы в 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 что является стандартным поведением, вы сразу же ударите ошибку рекурсии, так как все машинные триггеры будут обработаны мгновенно.

ответил(а) 2021-01-19T16:30:53+03:00 2 месяца, 3 недели назад
62

Существует fn.tcor https://github.com/kachayev/fn.py/blob/master/README.rst#trampolines-decorator. Но библиотека кажется невоспитанной. Вы можете искать оптимизацию хвостов в Python... Вы можете что-то найти.

ответил(а) 2021-01-19T16:30:53+03:00 2 месяца, 3 недели назад
44

Я надеюсь, что это может удовлетворить ваши ожидания

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

ответил(а) 2021-01-19T16:30:53+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема