Я хотел бы написать класс со следующим интерфейсом.
class Automaton:
""" A simple automaton class """
def iterate(self, something):
""" yield something and expects some result in return """
print("Yielding", something)
result = yield something
print("Got \"" + result + "\" in return")
return result
def start(self, somefunction):
""" start the iteration process """
yield from somefunction(self.iterate)
raise StopIteration("I'm done!")
def first(iterate):
while iterate("what do I do?") != "over":
continue
def second(iterate):
value = yield from iterate("what do I do?")
while value != "over":
value = yield from iterate("what do I do?")
# A simple driving process
automaton = Automaton()
#generator = automaton.start(first) # This one hangs
generator = automaton.start(second) # This one runs smoothly
next_yield = generator.__next__()
for step in range(4):
next_yield = generator.send("Continue...({})".format(step))
try:
end = generator.send("over")
except StopIteration as excp:
print(excp)
Идея состоит в том, что Automaton будет регулярно передавать значения вызывающей стороне, которая, в свою очередь, отправляет результаты / команды обратно в Automaton.
Загвоздка в том, что процесс принятия решения "somefunction" будет некоторой пользовательской функцией, над которой я не могу контролировать. Это означает, что я не могу ожидать, что он вызовет метод итерации перед yield from
впереди. Хуже всего то, что пользователь хочет подключить какую-то стороннюю функцию, которую он не может контролировать, внутри этого класса Automaton. Это означает, что пользователь может быть не в состоянии переписать свои somefunction
, чтобы он включал yield from
перед iterate
вызовами.
Чтобы было ясно: я полностью понимаю, почему при использовании функции first
зависает автомат. Мне просто интересно, есть ли способ изменить определение iterate
или start
, чтобы заставить работать функцию first
.