我最近在学习Twisted,现在我重新阅读了Deferred的一些基本文档,这是来自以下代码的示例代码:http://twistedmatrix.com/documents/12.3.0/core/howto/defer.html
注释掉第二个g = Getter()
怎么样?
会重新输入问题吗?关于如何避免此类问题,您是否有一些好主意?
from twisted.internet import reactor, defer
class Getter:
def gotResults(self, x):
"""
The Deferred mechanism provides a mechanism to signal error
conditions. In this case, odd numbers are bad.
This function demonstrates a more complex way of starting
the callback chain by checking for expected results and
choosing whether to fire the callback or errback chain
"""
if self.d is None:
print "Nowhere to put results"
return
d = self.d
self.d = None
if x % 2 == 0:
d.callback(x*3)
else:
d.errback(ValueError("You used an odd number!"))
def _toHTML(self, r):
"""
This function converts r to HTML.
It is added to the callback chain by getDummyData in
order to demonstrate how a callback passes its own result
to the next callback
"""
return "Result: %s" % r
def getDummyData(self, x):
"""
The Deferred mechanism allows for chained callbacks.
In this example, the output of gotResults is first
passed through _toHTML on its way to printData.
Again this function is a dummy, simulating a delayed result
using callLater, rather than using a real asynchronous
setup.
"""
self.d = defer.Deferred()
# simulate a delayed result by asking the reactor to schedule
# gotResults in 2 seconds time
reactor.callLater(2, self.gotResults, x)
self.d.addCallback(self._toHTML)
return self.d
def printData(d):
print d
def printError(failure):
import sys
sys.stderr.write(str(failure))
# this series of callbacks and errbacks will print an error message
g = Getter()
d = g.getDummyData(3)
d.addCallback(printData)
d.addErrback(printError)
# this series of callbacks and errbacks will print "Result: 12"
#g = Getter() #<= What about commenting this line out?
d = g.getDummyData(4)
d.addCallback(printData)
d.addErrback(printError)
reactor.callLater(4, reactor.stop)
reactor.run()
最佳答案
是的,如果您对第二个g = Getter()
进行注释,则会遇到问题。相同的Deferred
将触发两次,因为您将Deferred
存储在Getter
对象中。特别是,对getDummyData
的第二次调用将覆盖第一个Deferred
。
你不应该这样做。总的来说,我认为保留Deferred
对象不是一个好主意,因为它们只能触发一次,而且像您一样容易遇到问题。
您应该这样做:
def getDummyData(self, x):
...
d = defer.Deferred()
# simulate a delayed result by asking the reactor to schedule
# gotResults in 2 seconds time
reactor.callLater(2, self.gotResults, x, d)
d.addCallback(self._toHTML)
return d
和:
def gotResults(self, x, d):
"""
The Deferred mechanism provides a mechanism to signal error
conditions. In this case, odd numbers are bad.
This function demonstrates a more complex way of starting
the callback chain by checking for expected results and
choosing whether to fire the callback or errback chain
"""
if d is None:
print "Nowhere to put results"
return
if x % 2 == 0:
d.callback(x*3)
else:
d.errback(ValueError("You used an odd number!"))
请注意,在这种情况下,
Getter
没有状态,这很好,并且您不需要类!我的观点是,应使用
Deferred
使函数的调用者可以在结果可用时对结果执行某些操作。他们不应该被用于任何幻想。所以,我总是def func():
d = defer.Deferred()
...
return d
如果呼叫者出于某种原因必须坚持使用
Deferred
,则可以,但是我可以多次自由呼叫func
,而不必担心隐藏状态。关于python - 以下扭曲代码是否会重新输入问题?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19528527/