假设我有一些经理对象。这个对象的 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 也成为生成器来解决这个问题,原因有两个:
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
成为生成器,否则这个技巧就赢了'工作。
这一切有什么解决办法吗?也许我试图以错误的方式解决它?
(我知道这个问题又长又丑 - 这是我能做的最好的了。如果有什么不清楚的地方请告诉我,我会澄清的)
编辑
也许 pep 342是解决方案吗?
最佳答案
我之前的回答描述了如何在Python2中做到这一点,非常丑陋。但是现在我遇到了 PEP 380 : 委派给子生成器的语法。这正是你所要求的。唯一的问题是它需要 Python3。但这应该不是真正的问题。
这是它的工作原理:
def worker():
yield 1
yield 2
return 3
def main():
yield 0
value = yield from worker()
print('returned %d' % value)
yield 4
for m in main():
print('generator yields %d' % m)
结果是:
generator yields 0
generator yields 1
generator yields 2
returned 3
generator yields 4
异常以您期望的方式传递。
关于python - 在另一个函数中为生成器调用 yield,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3074784/