2011-10-24 55 views
4

我覺得我不是在編寫Twisted應用程序(.tac文件)時理解某些事情。在.py腳本中使用延遲對象很簡單,最後只需調用reactor.run(),但我沒有在任何扭曲的應用程序示例代碼中看到reactor.run()在Twisted應用程序中使用延遲對象

有人可以解釋:

  1. 爲什麼reactor.run()不扭曲的應用程序調用(或者如果這是一個錯誤的結論)
  2. 我如何使用雙絞線應用程序內遞延對象或許不調用reactor.run()
  3. 和編寫扭曲腳本與應用程序的一般差異。

回答

12

1.爲什麼在示例.tac文件中沒有調用reactor.run()

.tac文件意味着由「twistd」命令行工具加載,該工具爲您運行反應器。

運行反應堆是一次完成的任務,無論代碼是作爲程序的主要任務。大多數Twisted代碼實際上是某種插件,意味着要在更大的系統環境中運行。當反應器他們的工作是產生一個Application對象(Service對象的連接串),其開始了:

.tac文件的具體情況,他們從未想過要運行作爲獨立的Python程序運行。由於(例如)Service實現可能需要分離需要運行有特權和無特權的代碼,這是一個嚴格的過程,所以tac文件本身並沒有自己做很多工作,這一點很重要。如果工作在.tac本身中執行,它可能會作爲錯誤的用戶隨意執行。

2.如何在不需要調用reactor.run()的情況下使用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> 

這就是說,很多返回的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,你會看到Deferred得到一秒鐘後打電話回來,因爲交互提示已經運行的反應堆。

3. Twisted腳本與應用程序有什麼不同?

這些不是真正正式分離的術語。任何Python腳本都可以從Twisted導入代碼並以任何想要的方式使用它,所以很難說任何特定的屬性都適用於「腳本」,只不過它們是計算機程序:-)。

如果扭曲的應用程序,你的意思是一個.tac文件或插件,不同的是,這種代碼被分離到該版本的服務(在您tac文件或插件的頂級代碼)的一部分,實際完成這項工作的部分(privilegedStartService/startService/stopService上述頂級代碼設置的服務的實現)。另外,在這種情況下運行的代碼(即由twistd驅動)不需要運行反應器本身,因爲其本身將被設置並運行。這樣的代碼也因此必須小心,以避免進口twisted.internet.reactor,因爲twistd提供了使用不同反應堆(selectpollepollkqueue等),twistd之前自己導入反應器有機會來設置它會斷能力此功能。

+0

感謝您澄清'tac'文件的工作方式。導致我問這個問題的API是'twisted.enterprise.adbapi' API,它爲SQL查詢返回一個延遲。我發現它只會在'reactor.run()'被調用時纔會通過。我該如何將查詢添加到'twistd'創建的反應器循環中? – richard

+0

關於單個stackoverflow問題的三個問題可能就足夠了。 :) –