• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Python的Twisted框架中使用Deferred对象来管理回调函数

python 搞代码 4年前 (2022-01-09) 21次浏览 已收录 0个评论

首先抛出我们在讨论使用回调编程时的一些观点:

激活errback是非常重要的。由于errback的功能与except块相同,因此用户需要确保它们的存在。他们并不是可选项,而是必选项。

不在错误的时间点激活回调与在正确的时间点激活回调同等重要。典型的用法是,callback与errback是互斥的即只能运行其中一个。

使用回调函数的代码重构起来有些困难。

Deferred
Twisted使用Deferred对象来管理回调函数的序列。有些情况下可能要把一系列的函数关联到Deferred对象上,以便在在异步操作完成时按次序地调用(这些一系列的回调函数叫做回调函数链);同时还要有一些函数在异步操作出现异常时来调用。当操作完成时,会先调用第一个回调函数,或者当错误发生时,会先调用第一个错误处理回调函数,然后Deferred对象会把每个回调函数或错误处理回调函数的返回值传递给链中的下一个函数。
Callbacks
一个twisted.internet.defer.Deferred对象代表着在将来某个时刻一定会产生结果的一个函数。我们可以把一个回调函数关联到Deferred对象上,一旦这个Deferred对象有了结果,这个回调函数就会被调用。另外,Deferred对象还允许开发者为它注册一个错误处理回调函数。Deferred机制对于各种各样的阻塞或者延时操作都为开发者提供了标准化的接口。
from twisted.internet import reactor, defer

def getDummyData(inputData):  """  This function is a dummy which simulates a delayed result and  returns a Deferred which will fire with that result. Don't try too  hard to understand this.  """  print('getDummyData called')  deferred = defer.Deferred()  # simulate a delayed result by asking the reactor to fire the  # Deferred in 2 seconds time with the result inputData * 3  reactor.callLater(2, deferred.callback, inputData * 3)  return deferred def cbPrintData(result):  """  Data handling function to be added as a callback: handles the  data by printing the result  """  print('Result received: {}'.format(result)) deferred = getDummyData(3)deferred.addCallback(cbPrintData) # manually set up the end of the process by asking the reactor to# stop itself in 4 seconds timereactor.callLater(4, reactor.stop)# start up the Twisted reactor (event loop handler) manuallyprint('Starting the reactor')reactor.run()

多个回调函数
在一个Deferred对象上可以关联多个回调函数,这个回调函数链上的第一个回调函数会以Deferred对象的结果为参数来调用,而第二个回调函数以第一个函数的结果为参数来调用,依此类推。为什么需要这样的机制呢?考虑一下这样的情况,twisted.enterprise.adbapi返回一个Deferred对象——一个一个SQL查询的结果,可能有某个web窗口会在这个Deferred对象上添加一个回调函数,以把查询结果转换成HTML的格式,然后把Deferred对象继续向前传递,这时Twisted会调用这个回调函数并把结果返回给HTTP客户端。在出现错误或者异常的情况下,回调函数链不会被调用。

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 cbPrintData(result):  print(result)  def ebPrintError(failure):  import sys  sys.stderr.write(str(failure))  # this series of callbacks <b>本文来源gao@!dai!ma.com搞$$代^@码5网@</b>and errbacks will print an error messageg = Getter()d = g.getDummyData(3)d.addCallback(cbPrintData)d.addErrback(ebPrintError) # this series of callbacks and errbacks will print "Result: 12"g = Getter()d = g.getDummyData(4)d.addCallback(cbPrintData)d.addErrback(ebPrintError) reactor.callLater(4, reactor.stop)reactor.run()

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Python的Twisted框架中使用Deferred对象来管理回调函数
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址