异步python程序中的条件if与twisted

异步python程序中的条件if与twisted,python,python-2.7,twisted,Python,Python 2.7,Twisted,我正在创建一个使用Twisted模块和回调的程序。 但是,我一直有问题,因为异步部分崩溃了 我了解到(也从前面的问题中了解到…)回调将在某个点执行,但这是不可预测的 然而,我有一个特定的程序 j = calc(a) i = calc2(b) f = calc3(c) if s: combine(i, j, f) 现在,布尔值s由calc3执行的回调设置。显然,这会导致未定义的错误,因为在需要s之前不会执行回调。 但是,我不确定使用Twisted异步编程的if语句应该如何执行。我尝试了很多

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

我了解到(也从前面的问题中了解到…)回调将在某个点执行,但这是不可预测的

然而,我有一个特定的程序

j = calc(a)
i = calc2(b)
f = calc3(c)

if s:
  combine(i, j, f)
现在,布尔值
s
calc3
执行的回调设置。显然,这会导致未定义的错误,因为在需要
s
之前不会执行回调。 但是,我不确定使用Twisted异步编程的if语句应该如何执行
。我尝试了很多不同的方法,但都找不到有效的方法

是否有某种方法可以使用需要回调值的条件


另外,我使用
VIFF
进行安全计算(使用Twisted):

您必须将
if
放入回调中。您可以使用
延迟
来构造回调。

如前一个答案所述-预处理逻辑应该在回调链中处理,下面是简单的代码演示如何工作
C{DelayedTask}
是一个任务的虚拟实现,该任务将在将来发生并延迟触发

因此,我们首先构造一个特殊的对象-
C{ConditionalTask}
,它负责存储多个结果并为回调提供服务

calc1、calc2和calc3返回延迟,它们的回调指向
C{ConditionalTask}.x_callback

每个
C{ConditionalTask}.x_回调
都会调用
C{ConditionalTask}.process
,检查是否已注册所有结果并在完整集上激发

另外-
C{ConditionalTask}.C_callback
设置一个标志,指示是否应该处理数据

from twisted.internet import reactor, defer

class 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 deferred

def calc2(a):
    deferred = defer.Deferred()
    DelayedTask(5,deferred,a*2)
    return deferred

def calc3(a):
    deferred = defer.Deferred()
    DelayedTask(5,deferred,a*3)
    return deferred

def 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()

也许你要找的是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)
<>所以,请考虑让它看起来像这样:

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
的定义):


幸运的是,
calc3
的这个定义与上面的
gatherResults
/
计算的
代码块配合得很好。

calc
calc2
calc3
神奇的VIFF东西吗?或者它们是正常的函数,每个函数都返回一个延迟值?如果它们是神奇的VIFF东西,你能把你的问题扩展到包括它们的定义吗?所有函数都是“普通”函数,没有
VIFF
东西。除了
calc3
涉及共享(差异类型)和回调之外。不,这不是惯用的扭曲代码。它有完全不同的用途——允许解释过于简化的异步思想。结果并连接多个异步结果。我没有开始把他推到延迟列表和链式延迟/堆叠,以过度简化解决方案。你和@glyph现在都可以向我身上倒热熔岩。我还假设calc、calc2和calc3是可以同时调用的独立函数调用。我对此投了赞成票。我以前从未遇到过这样的结果。因此,对我来说,布尔值
s
也是一个新概念,它是由
calc3
执行回调的延迟函数定义的。因此,在设置布尔值之前,需要知道延迟值,这就是问题所在。利用这个答案中的一些想法,我成功地解决了回调问题。