python - Twisted deferred 上的生成器回调
问题描述
我正在尝试使用返回生成器的回调在 Twisted deferred 的回调链中跳转。考虑以下代码段:
from twisted.internet import defer
def callback_one(result):
print('Callback one: got "{}", will raise ZeroDivisionError'.format(result))
raise ZeroDivisionError
# yield
def errback_two(failure):
print('Errback two: handled "{}", recovering'.format(failure.type))
return 'recovered'
def callback_three(result):
print('Callback three: got "{}"'.format(result))
return 'Final result'
if __name__ == '__main__':
d = defer.Deferred()
d.addCallback(callback_one)
d.addErrback(errback_two)
d.addCallback(callback_three)
d.callback('First result')
输出是
Callback one: got "First result", will raise ZeroDivisionError
Errback two: handled "<class 'ZeroDivisionError'>", recovering
Callback three: got "recovered"
但是,如果未从我那里得到yield
注释callback_one
Callback three: got "<generator object callback_one at 0x104603af0>"
如果我理解正确,发生的事情是第一个回调返回一个生成器,直到为时已晚才评估该生成器,不会捕获异常,因此不会调用 errback。
总而言之,问题是:如果回调返回一个生成器,我如何以被延迟对象捕获的方式从中引发异常,从而触发 errback 链?
我是一名 Twisted 初学者,所以也许我正在尝试做的是一种不好的做法,甚至是不可能/真的很难实现,如果是这样,请告诉我。提前致谢!
解决方案
如果我理解正确,要获得诸如注释掉的结果yield
,您需要调用生成器。为此,您可以创建另一个仅执行生成器的函数并对您的主函数进行微小的更改:
def exec_gen(gen):
"""
Execute the generator
"""
for x in gen:
print(x)
# ...
if __name__ == '__main__':
d = defer.maybeDeferred(exec_gen, callback_one('First result'))
d.addErrback(errback_two)
d.addCallback(callback_three)
推荐阅读
- android - PreferenceHeaders 中图标的填充是否与 PreferenceScreens 不同?
- javascript - 输入类型颜色和 v-model 的 Vue 性能问题
- nginx - 如何调试未关闭的 CLOSE_WAIT 连接的原因?(tcpdump 等)
- spring-boot - Spring Cloud Stream Kafka 多重绑定
- mysql - 如何根据列的值对 Laravel 中的行进行排序?
- python - Python tkinter 如何使用网格粘性
- python-3.7 - icon_path 在 python 的 win10toast 模块中不起作用
- python - 如何仅翻译 DRF 中的自定义错误消息?
- lowpass-filter - 对正在进行的样本进行低通滤波器
- c - C程序:用链表改变队列的数据格式