[英]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.