[英]Using deferred objects inside Twisted applications
在编写Twisted应用程序(.tac文件)时,我觉得我不理解一些事情。 通过在最后调用reactor.run()
,可以很容易地在.py脚本中使用延迟对象,但我还没有看到在任何扭曲的应用程序示例代码中使用的reactor.run()
。
有人能解释一下:
reactor.run()
(或者如果这是一个错误的结论) reactor.run()
.tac
文件中没有调用.tac
reactor.run()
? .tac
文件应由“ twistd
”命令行工具加载,该工具为您运行反应器。
运行反应堆是一次完成的任务,无论代码是什么,都可以作为程序的主要部分。 大多数Twisted代码实际上是某种插件,意味着在更大的系统环境中运行。
在.tac
文件的特定情况下,它们永远不会作为独立的Python程序运行:它们的工作是生成一个Application
对象(带有一组附加的Service
对象),它们在reactor运行时启动。 重要的是tac
文件本身没有做太多工作,因为(例如)有问题的Service
实现可能需要分离需要运行特权和非特权的代码,这是一个严格的过程; 如果在.tac
本身中执行工作,它可能会随意执行为错误的用户。
reactor.run()
情况下在Twisted应用程序中使用Deferred
? 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>
也就是说,许多返回Deferred
API需要反应堆做一些工作才能最终调用它.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
中运行这个交互式示例,你会看到Deferred
get会在一秒后回调,因为交互式提示已经是运行反应堆。
这些并不是真正分开的术语。 任何Python脚本都可以从Twisted中导入代码并以任何方式使用它,因此很难说任何特定属性都适用于“脚本”,除了它们是计算机程序:-)。
如果Twisted Application是指.tac
文件或插件,不同之处在于这种代码被分离到构建服务的部分( tac
文件或插件中顶级代码)和部分实际上做了工作(顶级代码设置的服务的privilegedStartService
/ startService
/ stopService
实现)。 此外,在此上下文中运行的代码(即由twistd
驱动)不需要运行反应器本身,因为一个将由twistd
本身设置和运行。 因此,这样的代码也必须小心避免导入twisted.internet.reactor
,因为twistd
提供了使用不同反应器( select
, poll
, epoll
, kqueue
等)并在twistd
有机会设置它之前自己导入反应器的能力。将破坏此功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.