предположим, у меня есть какой-то объект менеджера. API этого объекта имеет функцию main_hook
, которая получает в качестве аргумента другую функцию f
и выполняет заданный f
в цикле, делая некоторые вещи между каждой итерацией:
def main_hook(self,f):
while (self.shouldContinue()):
#do some preparations
f(self)
#do some tear down
Теперь у меня также есть (точнее, хотел бы иметь ) функцию stop_and_do_stuff
, которая однажды вызвана, останавливает main_hook
мертвую на своих треках, возвращает элемент управления в зависимости от того, какая функция называется main_hook
, и после того, как этот функционал завершит свою работу, верните управление main_hook и продолжайте. В основном результат будет таким же, как и
def main_hook(self,f):
while (self.shouldContinue()):
#do some preparations
yield
#do some tear down
За исключением того, что вместо yield
я хочу позвонить на f()
, в то же время давая f
возможность звонить self.stop_and_do_stuff()
Я не могу обойти это, сделав f также генератором по 2 причинам:
1. f
не является частью моего API - он предоставлен мне пользователем, использующим мою библиотеку
2. Даже если бы он мог попросить его использовать yield, место в коде, в котором ему нужно будет вызывать stop_and_do_stuff
, не будет находиться непосредственно внутри f, скорее в каком-то месте в стеке функций, который будет внутри f()
, но не непосредственно в нем, например
def h(manager):
#do stuff
if should stop:
manager.stop_and_do_stuff()
#do more stuff
def g(manager):
#some stuff
if should stop:
manager.stop_and_do_stuff()
#more stuff
if should stop again:
manager.stop_and_do_stuff()
if should call h:
h()
def f(manager):
g(manager)
, поэтому, если я решу сделать f
генератором, мне также нужно сделать g
генератором и также h
, иначе этот трюк не сработает.
Есть ли какое-нибудь решение для всего этого? может я пытаюсь решить это неправильно?
(я знаю, что этот вопрос длинный и безобразный - это лучшее, что я мог сделать. Если что-то не понятно, пожалуйста, скажите мне, и я уточню это)
EDIT
Может быть pep 342 это решение?