在Twisted应用程序中使用延迟对象

时间:2011-10-24 19:00:24

标签: python twisted

我觉得我在编写Twisted应用程序(.tac文件)时并不理解某些内容。在最后调用reactor.run()可以很容易地在.py脚本中使用延迟对象,但我没有看到任何扭曲的应用程序示例代码中使用的reactor.run()

有人可以解释一下:

  1. 为什么在扭曲的应用程序中没有调用reactor.run()(或者如果这是一个错误的结论)
  2. 如何在不调用reactor.run()
  3. 的情况下在扭曲的应用程序中使用延迟对象
  4. 和编写扭曲脚本与应用程序的一般差异。

1 个答案:

答案 0 :(得分:12)

1。为什么reactor.run()未在示例.tac文件中调用?

.tac文件应由“twistd”命令行工具加载,该工具为您运行反应堆。

运行反应堆是一次完成的事情,无论代码是什么,都可以作为程序的主要部分。大多数Twisted代码实际上是某种插件,意味着在更大的系统环境中运行。

.tac文件的特定情况下,它们永远不会作为独立的Python程序运行:它们的工作是生成一个Application对象(附带一堆{{1}在反应堆运行时启动的对象)。重要的是Service文件本身没有做太多工作,因为(例如)有问题的tac实现可能需要分离需要运行特权和非特权的代码,这是一个严格的处理;如果在Service本身执行工作,则可能会随意执行错误的用户。

2。如何在Twisted应用程序中使用.tac而不调用Deferred

reactor.run()只是一种管理回调链的机制。你不需要调用Deferred,或者甚至根本没有反应堆来使用它们。例如:

reactor.run()

也就是说,许多返回>>> from twisted.internet.defer import Deferred >>> d = Deferred() >>> def hello(result): ... print "'d' was fired:", result ... return result + 3 ... >>> d.addCallback(hello) <Deferred at ...> >>> print d <Deferred at ...> >>> d.callback(7) 'd' was fired: 7 >>> print d <Deferred at ... current result: 10> 的API需要反应堆做一些工作才能最终调用Deferred。例如,如果你这样做......

.callback()

......除非有人经营反应堆,否则你将永远坐在那里等待着火。在此之前不会打印任何内容。

但是,如果反应堆已经在运行 - 例如,如果您在>>> from twisted.internet.task import deferLater >>> from twisted.internet import reactor >>> deferLater(reactor, 1.0, lambda: 20).addCallback(hello) <Deferred at ...> >>> 而不是python -m twisted.conch.stdio中运行此交互式示例,您会看到python被召回一秒钟之后,因为该交互式提示已经在运行反应堆。

3。 Twisted脚本与应用程序之间有什么区别?

这些并非真正正式分开的术语。任何Python脚本都可以从Twisted中导入代码并以任何方式使用它,因此很难说任何特定属性都适用于“脚本”,除了它们是计算机程序: - )。

如果Twisted Application是指Deferred文件或插件,不同之处在于这种代码被分离到构建服务的部分({{1中的顶级代码)文件或插件)以及实际完成工作的部分(.tac / tac / privilegedStartService实现了顶级代码设置的服务。此外,在此上下文中运行的代码(即由startService驱动)不需要运行反应器本身,因为一个将由stopService本身设置和运行。因此,此类代码也必须小心避免导入twistd,因为twistd提供了使用不同反应堆的能力(twisted.internet.reactortwistd,{ {1}},select等)并在poll有机会设置之前自行导入反应堆会破坏此功能。