Python Twisted:如何中断延迟的回调链

Python Twisted:如何中断延迟的回调链,python,twisted,deferred,Python,Twisted,Deferred,我的问题是:我有一个延迟回调和错误回调。我需要在特定错误返回后停止该过程。换句话说,如果调用了errback的特定函数,我需要获取它的返回,而不处理以下回调 from twisted.internet import defer from twisted.python import failure, util class Test (object): @classmethod def handleFailure(self, f): print "handleFailure"

我的问题是:我有一个延迟回调和错误回调。我需要在特定错误返回后停止该过程。换句话说,如果调用了errback的特定函数,我需要获取它的返回,而不处理以下回调

from twisted.internet import defer
from twisted.python import failure, util


class Test (object):

@classmethod
def handleFailure(self, f):
    print "handleFailure"
    f.trap(RuntimeError)
    return '0', 'erro'

@classmethod
def handleResult(self, result, message):
    print "handleResult of %s. Old results %s, %s: " % (message, result[0], result[1])
    return 1, 'ok'

@classmethod
def doFailure (self, result, message):
    print "handleResult of %s. Old results %s, %s: " % (message, result[0], result[1])
    raise RuntimeError, "whoops! we encountered an error"


@classmethod
def deferredExample(self):
    d = defer.Deferred()
    # 1o. call without error
    d.addCallback(Test.handleResult, 'call 1')
    # 2o. call without error
    d.addCallback(Test.handleResult, 'call 1')
    # 3o. call causes the failure
    d.addCallback(Test.doFailure,    'call 3')
    # the failure calls the error back 
    d.addErrback (Test.handleFailure) # - A -
    # after error back, the next call back is called
    d.addCallback(Test.handleResult, 'call 4')  # - B -
    # and the last call back is called   
    d.addCallback(Test.handleResult, 'call 5')  # - C -

    d.callback("success")
    return d.result[0], d.result[1]

if __name__ == '__main__': 
#    behindTheScenes("success")
    print "\n-------------------------------------------------\n"
    global num; num = 0
    tst = Test()
    rtn1, rtn2 = tst.deferredExample()
    print "RTN: %s %s" % (rtn1, rtn2)
这段代码是一个简单的版本,反映了我的需要。在-A-过程之后,我需要对-B-和-C-进行baypass,最后,响应是“0,erro”,而不是“1,ok”

我目前的报税表:

handleResult of call 1. Old results s, u: 
handleResult of call 1. Old results 1, ok: 
handleResult of call 3. Old results 1, ok: 
handleFailure
handleResult of call 4. Old results 0, erro: 
handleResult of call 5. Old results 1, ok: 
RTN: 1 ok
我想:

handleResult of call 1. Old results s, u: 
handleResult of call 1. Old results 1, ok: 
handleResult of call 3. Old results 1, ok: 
handleFailure
RTN: 0 erro
我该怎么做


提前感谢

这是一个非常有趣的问题。Twisted没有提供任何用于在错误发生后修改回调链的文档化API。如果您真的想中断errback中的处理,您可以随时引发错误,而不是捕获错误

但是,如果您真的想在某些情况下删除延迟的所有回调,您可以使用simple hack。回调作为简单对象属性保留在延迟状态,请参见此处:如果您只需将此属性重置为空列表,所有回调将被删除,处理将停止

@classmethod
def handleFailure(self, f, d):
    print "handleFailure"
    f.trap(RuntimeError)
    d.callbacks = []
    return '0', 'erro'

这是您希望的工作方式,但似乎有些粗糙,所以我很乐意阅读其他用户的想法。这里有更多关于这个问题的讨论:讨论表明您试图做的有点违背Twisted的精神。

这是一个非常好的问题,我很想听听是否有人对此有答案。我在这里这里有一些关于这个问题的有趣的讨论:我不确定你想做的事情是否可行。基本上,如果你想完全停止执行,为什么要从errback返回结果?也许你可以简单地在errback中引发错误?这将停止处理。如果你不引发错误,则假设你想继续,它会移动到on、 我正在使用回调链来控制和验证http get请求(REST web服务调用)的串联结果。当结果符合我的预期时,流程将继续。否则,我将引发调用errback失败(返回修改响应的方法)。但是,如果在调用序列中有一个失败,那么以下内容就无关紧要了。感谢@Pawelmiceh提供的提示。感谢@Pawelmiceh。效果很好。最好不要这样做,您最好按照
errback
链来做:
return failure in handleFailure来遵循errback链,或者返回其他人来遵循回调链