Python twisted defer 与 getProcessOutputAndValue 问题

1 投票
2 回答
1019 浏览
提问于 2025-04-16 12:43

大家好,

这个程序看起来很简单,但我不明白哪里出了问题。运行程序时,它只是一直等待,控制台上什么也不输出,按下控制键+C也没有任何反应。请给点建议。

我理解的情况是这样的:

(i) Reactor(反应器)开始运行,callLater会在“0”秒后调用runProgram。

(ii) runProgram从getProcessOutputAndValue那里得到了一个延迟对象(deferred),我为它添加了Callback和Errback,并且把reactor.stop()作为“两个”回调。

我现在的期望是,当命令执行完成后,延迟对象的Callback(或者在失败时的Errback)应该被调用。最后,由于指定了addBoth,所以reactor.stop()应该被调用,从而停止反应器。

from twisted.internet.utils import getProcessOutputAndValue
from twisted.internet import reactor

def printResult(result):
   print u'Result is %s' % result

def printError(reason):
   print u'Error is %s' % reason

def stopReactor(r):
   print u'Stopping reactor'
   reactor.stop()
   print u'Reactor stopped'

def runProgram():
   command = ['lrt']
   d = yield getProcessOutputAndValue('echo', command)
   d.addCallback(printResult)
   d.addErrback(printError)
   d.addBoth(stopReactor)

reactor.callLater(0, runProgram)
reactor.run()

2 个回答

2

你不需要用到 yield,因为 getProcessOutputAndValue 返回的结果已经是一个 Deferred 对象了。

1

正如之前所说,那里用不到 yield。要使用 yield,你需要把 runProgram 改写成这样:

from twisted.internet import defer

@defer.inlineCallbacks
def runProgram():
    command = ['lrt']
    try:
        result = yield getProcessOutputAndValue('echo', command)
        printResult(result)
    except e:
        printError(e)
        stopReactor()

我个人建议还是使用明确的延迟调用。等你理解了这个概念后,会更容易掌握,而且和其他的 twisted 代码结合得也更顺畅。

撰写回答