这太破碎了,我希望你对我很仁慈:
reactor.callLater(0, myFunction, parameter1).addCallback(reactor.stop)
reactor.run()
myFunction
会返回延迟。
我希望很清楚我想做什么:
myFunction
。这就是我使用0作为延迟参数的原因。除了callLater之外没有别的办法吗?传递它的延迟为0看起来很有趣。myFunction
完成任务后立即停止反应堆。到目前为止我遇到的问题:
AttributeError: DelayedCall instance has no attribute 'addCallback'
。很公平!如何在由myFunction
启动的回调链中放回调?exceptions.TypeError: stop() takes exactly 1 argument (2 given)
。 要解决第二个问题,我必须定义一个特殊功能:
def stopReactor(result):
gd.log.info( 'Result: %s' % result)
gd.log.info( 'Stopping reactor immediatelly' )
reactor.stop()
并将代码更改为:
reactor.callLater(0, myFunction, parameter1).addCallback(stopReactor)
reactor.run()
(由于callLater问题仍无效,但stopReactor
现在可以正常工作)
除了定义一个额外的函数之外,真的没有办法调用reactor.stop
吗?
答案 0 :(得分:21)
IReactorTime.callLater
和Deferred
由twisted.internet.task.deferLater
混合在一起。
from twisted.internet import reactor, task
d = task.deferLater(reactor, 0, myFunction, parameter1)
d.addCallback(lambda ignored: reactor.stop())
reactor.run()
答案 1 :(得分:1)
我想在myFunction完成任务后立即停止反应堆。
那么,创建一个包装器来执行myFunction的工作,然后停止反应器?
def wrapper(reactor, *args):
myFunction(*args)
reactor.stop()
reactor.callLater(0, wrapper, reactor, ...)
答案 2 :(得分:0)
您需要将回调附加到myFunction返回的延迟,因为callLater不返回函数。这样的事情可能有用:
reactor.callLater(0, lambda: myFunction(parameter1).addCallback(lambda _: reactor.stop())
但这未经过测试。
您需要编写一个新函数(此处为lambda _:reactor.stop()),因为对延迟的回调始终将结果记录到那时。如果您发现自己想要使用回调来处理副作用而又不关心经常传播值,那么您可以定义一个小辅助函数:
def ignoringarg(f):
return lambda _: f()
然后做:
reactor.callLater(0, lambda: myFunction(paramater1).addCallback(ignoringarg(reactor.stop)))
(对于__rshift__
类定义Deferred
(和就地模拟)真的很简洁,所以你可以这样做:myFunction(parameter1) >> reactor.stop
,当你想要的时候放弃参数,或者myFunction(parameter1) >>= someotherfunc
当你想传播参数时。如果你认为滥用haskellish语法是“整洁的”,无论如何。)
答案 3 :(得分:0)
如果你需要通过某个动作触发回调,那就去做吧(可能不需要返回deferred或smth)。 只是为了澄清事情(使用纯粹的延期):
from twisted.internet import reactor, defer
# That will be our deferred to play with
# it has callback and errback methods
d = defer.Deferred()
def my_function(x):
print 'function', x
# need to trigger deferred upon function run?
# Lets tell it to do so:
d.callback(x)
# That's our callback to run after triggering `d`
def d_callback(y):
print 'callback ', y
# now let's bind that callback to be actually launched by `d`
d.addCallback(d_callback)
# now adding another callback just to stop reactor
# note lambda simply helps to agree number of arguments
d.addCallback(lambda data: reactor.stop())
# so we'll call `my_function` in 2 secs, then it runs
# then it triggers `d` to fire its callbacks
# then `d` actually detonates the whole chain of its added callbacks
reactor.callLater(2, my_function, 'asdf') # 'asdf' is some stupid param
# Here how it works
print 'Lets start!'
reactor.run()
print 'Done!'