Можно ли написать делегаты произвольной глубины в Python? - PullRequest
0 голосов
/ 21 февраля 2020

Я хотел бы написать класс со следующим интерфейсом.

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...