如果在异步python程序中扭曲则有条件

我正在创建一个使用Twisted模块和回调的程序。但是,我一直遇到问题,因为异步部分损坏了。


我已经从先前的问题中了解到。回调将在某个时刻执行,但这是不可预测的。


但是,我有一个特定的程序


j = calc(a)

i = calc2(b)

f = calc3(c)


if s:

  combine(i, j, f)

现在,布尔值s是由所完成的回调设置的calc3。显然,这会导致未定义的错误,因为在s需要之前没有执行回调。但是,我不确定如何SHOULD使用Twisted进行异步编程的if语句。我一直在尝试许多不同的事情,但是找不到任何可行的方法。


有什么方法可以使用需要回调值的条件?


当年话下
浏览 169回答 2
2回答

ITMISS

也许您正在寻找的是twisted.internet.defer.gatherResults:d = gatherResults([calc(a), calc2(b), calc3(c)])def calculated((j, i, f)):    if s:        return combine(i, j, f)d.addCallback(calculated)但是,这仍然存在s未定义的问题。我不太清楚你期望如何s定义。如果它是中的局部变量calc3,则需要返回它,以便调用者可以使用它。也许calc3看起来像这样:def calc3(argument):    s = bool(argument % 2)    return argument + 1因此,请考虑使它看起来像这样:Calc3Result = namedtuple("Calc3Result", "condition value")def calc3(argument):    s = bool(argument % 2)    return Calc3Result(s, argument + 1)现在,您可以重写调用代码,这样它实际上可以工作:您在这里问的内容有点不清楚。听起来您知道什么是回调,但是如果是这样,那么您应该可以自己得出以下答案:d = gatherResults([calc(a), calc2(b), calc3(c)])def calculated((j, i, calc3result)):    if calc3result.condition:        return combine(i, j, calc3result.value)d.addCallback(calculated)或者,根据您的以下评论,可能calc3看起来更像这样(这是我要做出的最后一个猜测,如果有误,并且您想输入更多信息,请实际上分享的定义calc3):def _calc3Result(result, argument):    if result == "250":        # SMTP Success response, yay        return Calc3Result(True, argument)    # Anything else is bad    return Calc3Result(False, argument)def calc3(argument):    d = emailObserver("The argument was %s" % (argument,))    d.addCallback(_calc3Result)    return d幸运的是,这个定义calc3将与上面的gatherResults/calculated代码块一起很好地工作。

慕桂英4014372

如先前的回答所述-处理逻辑应在回调链中处理,下面是简单的代码演示如何实现此功能。C{DelayedTask}是将来执行的任务的虚拟实现,并且延迟提供火灾。因此,我们首先构造一个特殊的对象-C{ConditionalTask}它负责存储多个结果并为回调提供服务。calc1,calc2和calc3返回延迟的变量,这些延迟的回调指向C{ConditionalTask}.x_callback。每个人都会C{ConditionalTask}.x_callback进行呼叫,C{ConditionalTask}.process以检查是否所有结果都已注册,并在全套条件下触发。另外-C{ConditionalTask}.c_callback设置标记是否完全不应该处理数据。from twisted.internet import reactor, deferclass DelayedTask(object):    """    Delayed async task dummy implementation    """    def __init__(self,delay,deferred,retVal):        self.deferred = deferred        self.retVal = retVal        reactor.callLater(delay, self.on_completed)    def on_completed(self):        self.deferred.callback(self.retVal)class ConditionalTask(object):    def __init__(self):        self.resultA=None        self.resultB=None        self.resultC=None        self.should_process=False    def a_callback(self,result):        self.resultA = result        self.process()    def b_callback(self,result):        self.resultB=result        self.process()    def c_callback(self,result):        self.resultC=result        """        Here is an abstraction for your "s" boolean flag, obviously the logic        normally would go further than just setting the flag, you could        inspect the result variable and do other strange stuff        """        self.should_process = True         self.process()    def process(self):        if None not in (self.resultA,self.resultB,self.resultC):            if self.should_process:                print 'We will now call the processor function and stop reactor'                reactor.stop()def calc(a):    deferred = defer.Deferred()    DelayedTask(5,deferred,a)    return deferreddef calc2(a):    deferred = defer.Deferred()    DelayedTask(5,deferred,a*2)    return deferreddef calc3(a):    deferred = defer.Deferred()    DelayedTask(5,deferred,a*3)    return deferreddef main():    conditional_task = ConditionalTask()    dFA = calc(1)    dFB = calc2(2)    dFC = calc3(3)    dFA.addCallback(conditional_task.a_callback)    dFB.addCallback(conditional_task.b_callback)    dFC.addCallback(conditional_task.c_callback)    reactor.run()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python