Twisted Deferred.addCallBack()vs. yield和@inlineDeferred

时间:2010-10-08 21:00:20

标签: python twisted

有没有理由使用其中一个?

他们有相同的表现吗?

3 个答案:

答案 0 :(得分:15)

我倾向于使用inlineCallbacks进行多步骤初始化(例如auth)到一些服务,例如,每个后续步骤依赖于前一步骤的结果。除了这些情况之外,我倾向于发现inlineCallbacks可能会导致懒惰的编程,这会使减慢您的应用。

以下是一个例子:

@defer.inlineCallbacks
def some_func():
    res1 = yield call1()
    res2 = yield call2()
    ... do something with res1 and res2 ...

如果call1call2是您要并行化的完全独立的调用,则此函数将最终序列化这些调用。要将此转换为并行调用,您应该:

@defer.inlineCallbacks
def some_func_better():
    d1 = call1()
    d2 = call2()
    res1 = yield d1
    res2 = yield d2

通过这种方式,你可以同时运行call1和call2,但是当你进来时你等待结果。所以,虽然可以获得与缺货相同的好处,但似乎inlineCallbacks也是如此易于实施前一种解决方案。

另外,请记住,您仍然必须在所有yield调用周围包装try...except块,因为它们是在代码中捕获错误的唯一方法(除非{{1}的调用函数函数处理该级别的错误。)

所以,我发现这不是一个性能本身的问题,而是一个良好的习惯会让我建议反对inlineCallbacks 一般 - 他们对于快速代码片段,多阶段初始化例程或测试,例如,它仍然很棒。

答案 1 :(得分:2)

差异应该是微妙的。如果这段代码确实经常运行,那么也许你应该研究一下你的应用程序设计。否则,采用更容易阅读的变体,必须在未来几个月或几年内完成它的头和尾。

编辑:如果你真的想知道,这里是你如何找到的(毕竟,它可能是你的python版本特定的实现):在紧密循环中运行两个版本并测量时间。增加循环计数,直到版本之间的时差远远大于多次运行中相同版本的时间差异。更改python版本,操作系统等后重复。

答案 2 :(得分:0)

使用defer.inlineCallbacks可以使您的代码更易于阅读..

它有点像corountine样式:你既不阻止调用也不使用回调链来构建整个逻辑。这很直观。