2009-01-10 74 views
7

我有一個嵌入在應用程序中的python解釋器。應用程序需要很長時間才能啓動,並且我無法在不重新啓動整個應用程序的情況下重新啓動解釋器。我想要做的是基本上保存解釋者的狀態並輕鬆地返回到該狀態。靜靜地重新啓動Python解釋器

我開始時將python解釋器啓動的所有模塊的名稱存儲在sys.modules中,然後在請求時從sys.modules中刪除所有新模塊。這似乎使解釋器準備重新導入相同的模塊,即使它之前已經導入了它們。但是,這似乎並不適用於所有情況,例如使用單例類和靜態方法等。

我寧可不在此解釋器中嵌入另一個解釋器(如果可以避免),因爲易於存在能夠使用API​​的應用程序將會丟失(以及包含我想象中的輕微速度命中)。

那麼,有沒有人知道我可以存儲解釋器的狀態,然後返回到這樣的方式,以便它可以應付所有情況?

感謝,

回答

4

從ActiveState的食譜試試這個代碼:http://code.activestate.com/recipes/572213/

它,所以它支持在shell控制檯中定義酸洗東西延伸鹹菜。從理論上講,你應該只能夠以酸洗主要模塊,可以根據自己的文檔:

import savestate, pickle, __main__ 
pickle.dump(__main__, open('savestate.pickle', 'wb'), 2) 
+0

這看起來很有前途的謝謝,我會更深入地研究一下。 – Dan 2009-01-11 16:57:00

0

一個非常哈克和bug容易的方法可能是簡單的拷貝存儲到一個文件,以便它可以在下次啓動時加載回一個C模塊。但是因爲我無法想象這會始終正常工作,酸洗會成爲一種替代方案嗎?

如果你能夠使你的所有模塊都可以被pickleable,那麼你應該能夠在globals()中醃製所有的東西,這樣它就可以重新加載了。

0

如果您事先知道正在使用的模塊,類,函數,變量等,您可以將它們醃製到磁盤並重新加載。如果您的環境包含許多未知因素,我無法確定解決問題的最佳方式。雖然,醃製全球和當地人可能就足夠了。

1

我建議解決根源問題。

「應用程序需要很長的時間來 開始了,我沒有能力 重新解釋,而不 重新啓動整個應用程序」

我懷疑這實際上是100%真實。如果整體申請是國會行爲的結果,那麼不能改變。但是,如果整個應用程序是由真人編寫的,那麼找到並移動代碼重新啓動Python解釋器應該是可能的。它比更便宜,更簡單,更可靠否則,您可能會採取措施解決問題。

+0

不是這種情況 - 應用程序是每年僅發佈一次的主要軟件。在引入此功能之前,黑客是加速開發的唯一解決方案。 – Dan 2009-01-11 12:15:53

+1

我希望我的時間值得這麼多!這是我將不得不在一兩個小時內實施的事情,以便讓我的生活變得更加輕鬆。如果效果不好,我們會繼續使用現有的系統... – Dan 2009-01-11 16:54:33

1

在sys.modules中存儲python解釋器啓動的所有模塊的名稱,然後從sys中刪除所有新模塊。模塊在需要時。這似乎使解釋器準備重新導入相同的模塊,即使它之前已經導入了它們。

模塊重載強制方法可以在某些情況下工作,但有點多毛。總結:

  • 您需要確保所有彼此具有依賴關係的模塊都被一次性重新加載。因此,任何'import y'或'from y import'模塊'x'必須在模塊'y'的同時從sys.modules中刪除。

  • 如果您的應用程序或任何其他活動模塊正在使用線程,此過程將需要使用鎖保護。

  • 在其他模塊中留下鉤子指向自身的任何模塊都無法重新加載,因爲對舊模塊的引用將保留在未加載/不可加載的代碼中。這包括異常鉤子,信號,警告過濾器,編碼,猴子補丁等等。如果您開始輕率地重新加載包含其他人的代碼的模塊,您可能會驚訝他們多長時間一次這樣做,這可能會導致微妙和奇怪的錯誤。

因此,要得到它的工作,你需要有相互依賴的模塊之間定義良好的界限 - 「是它在初始啓動時輸入」可能是還不夠好 - 並確保他們」很好地封裝,沒有像猴子修補這樣的意外的依賴關係。

這可以基於文件夾,因此例如/ home/me/myapp/lib中的任何內容都可以作爲一個單元重新加載,同時保留其他模塊 - 尤其是stdlib的內容。 /usr/lib/python2.x/通常不可靠重新加載。如果需要的話,我可以在尚未發佈的webapp重裝包裝器中獲得此代碼。

最後:

  • 您需要了解sys.modules中的內部一點點,特別是它留下了一堆「無」值來表示失敗的相對進口。如果在刪除其他模塊值的同時不刪除它們,隨後導入模塊的嘗試可能(有時)最終導入「無」,從而導致混淆錯誤。

這是一個令人討厭的實現細節,它可能會在未來的某個Python版本中更改和破壞您的應用程序,但這是以不支持的方式使用sys.modules播放的代價。