我觉得我在编写Twisted应用程序(.tac文件)时并不理解某些内容。在最后调用reactor.run()
可以很容易地在.py脚本中使用延迟对象,但我没有看到任何扭曲的应用程序示例代码中使用的reactor.run()
。
有人可以解释一下:
reactor.run()
(或者如果这是一个错误的结论)reactor.run()
答案 0 :(得分:12)
reactor.run()
未在示例.tac
文件中调用? .tac
文件应由“twistd
”命令行工具加载,该工具为您运行反应堆。
运行反应堆是一次完成的事情,无论代码是什么,都可以作为程序的主要部分。大多数Twisted代码实际上是某种插件,意味着在更大的系统环境中运行。
在.tac
文件的特定情况下,它们永远不会作为独立的Python程序运行:它们的工作是生成一个Application
对象(附带一堆{{1}在反应堆运行时启动的对象)。重要的是Service
文件本身没有做太多工作,因为(例如)有问题的tac
实现可能需要分离需要运行特权和非特权的代码,这是一个严格的处理;如果在Service
本身执行工作,则可能会随意执行错误的用户。
.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
被召回一秒钟之后,因为该交互式提示已经在运行反应堆。
这些并非真正正式分开的术语。任何Python脚本都可以从Twisted中导入代码并以任何方式使用它,因此很难说任何特定属性都适用于“脚本”,除了它们是计算机程序: - )。
如果Twisted Application是指Deferred
文件或插件,不同之处在于这种代码被分离到构建服务的部分({{1中的顶级代码)文件或插件)以及实际完成工作的部分(.tac
/ tac
/ privilegedStartService
实现了顶级代码设置的服务。此外,在此上下文中运行的代码(即由startService
驱动)不需要运行反应器本身,因为一个将由stopService
本身设置和运行。因此,此类代码也必须小心避免导入twistd
,因为twistd
提供了使用不同反应堆的能力(twisted.internet.reactor
,twistd
,{ {1}},select
等)并在poll
有机会设置之前自行导入反应堆会破坏此功能。