7

アプリケーション内に Python インタープリターが埋め込まれています。アプリケーションの起動に時間がかかり、アプリケーション全体を再起動しないとインタープリターを再起動できません。私がやりたいことは、本質的にインタープリターの状態を保存し、その状態に簡単に戻ることです。

まず、Python インタープリターが開始した sys.modules にすべてのモジュールの名前を格納し、要求されたときに sys.modules からすべての新しいモジュールを削除しました。これにより、インタープリターは同じモジュールを以前にインポートしたことがあるにもかかわらず、それらを再インポートする準備ができているように見えます。ただし、シングルトン クラスや静的メソッドの使用など、すべての状況でこれが機能するとは限りません。

アプリケーション API の使いやすさが失われるため、回避できる場合は、このインタープリター内に別のインタープリターを埋め込みたくありません (また、わずかな速度低下も含まれると思います)。

それで、インタープリターの状態を保存してからこれに戻って、すべての状況に対処できる方法を知っている人はいますか?

ありがとう、

ダン

4

5 に答える 5

4

ActiveState レシピからこのコードを試してください: http://code.activestate.com/recipes/572213/

これは pickle を拡張するので、シェル コンソールで定義されたすべての pickle 化をサポートします。理論的には、ドキュメントによると、メインモジュールをピクルできるはずです。

import savestate, pickle, __main__
pickle.dump(__main__, open('savestate.pickle', 'wb'), 2)
于 2009-01-10T21:19:39.193 に答える
1

根本原因の問題に取り組むことをお勧めします。

「アプリケーションの起動に時間がかかり、アプリケーション全体を再起動せずにインタープリターを再起動することはできません。」

これが実際に100%真実であるとは思えません。全体的な申請が議会制定法の結果である場合は、変更することはできません。しかし、アプリケーション全体が実際の人によって作成された場合は、コードを見つけて移動し、Pythonインタープリターを再起動できるはずです。問題をハックするために行う他のどの方法よりも安く、簡単で、信頼性があります。

于 2009-01-10T21:46:02.277 に答える
1

Pythonインタープリターが開始したsys.modulesにすべてのモジュールの名前を保存し、要求されたときにsys.modulesからすべての新しいモジュールを削除します。これにより、インタープリターは同じモジュールを以前にインポートしたことがあるにもかかわらず、それらを再インポートする準備ができているように見えます。

module-reload-forcing アプローチは、状況によっては機能するようにすることもできますが、少し面倒です。要約すれば:

  • 相互に依存関係を持つすべてのモジュールが一度にすべて再ロードされるようにする必要があります。したがって、'import y' または 'from y import ...' を実行するモジュール 'x' は、モジュール 'y' と同時に sys.modules から削除する必要があります。

  • アプリまたは他のアクティブなモジュールがスレッドを使用している場合、このプロセスはロックで保護する必要があります。

  • 古いモジュールへの参照が再ロードされていない/再ロード不可能なコードに残るため、他のモジュールで自分自身を指すフックを残すモジュールは、有効に再ロードできません。これには、例外フック、シグナル、警告フィルター、エンコーディング、モンキー パッチなどが含まれます。他の人のコードを含むモジュールを気軽にリロードし始めると、彼らがそのようなことを頻繁に行うことに驚くかもしれません。

したがって、それを機能させるには、相互に依存するモジュール間に明確に定義された境界が必要です-「最初の起動時にインポートされたか」はおそらく十分ではありません-そして、それらが予期しない依存関係なしにうまくカプセル化されていることを確認しますモンキーパッチ。

これはフォルダーに基づいている可能性があるため、たとえば /home/me/myapp/lib 内のものはすべてユニットとしてリロードできますが、他のモジュールはそのままにしておくことができます。特に stdlib の内容などです。/usr/lib/python2.x/ は、一般的にリロードが信頼できません。必要に応じて、まだリリースされていない webapp リロード ラッパーにこのためのコードがあります。

ついに:

  • sys.modules の内部について少し知っておく必要があります。具体的には、失敗した相対インポートを示すために多数の「None」値が残されるということです。他のモジュール値を削除するのと同時にそれらを削除しないと、その後モジュールをインポートしようとすると、(場合によっては) 'None' がインポートされ、混乱を招くエラーが発生する可能性があります。

これは厄介な実装の詳細であり、将来の Python バージョンでアプリが変更されて壊れる可能性がありますが、サポートされていない方法で sys.modules をいじる代償です。

于 2009-01-11T00:24:43.283 に答える
0

使用中のモジュール、クラス、関数、変数などを事前に知っている場合は、それらをディスクにピクルしてリロードできます。あなたの環境に多くの不明な点が含まれている場合、問題に取り組む最善の方法が頭の中でわかりません。ただし、グローバルとローカルをピクルするだけで十分な場合があります。

于 2009-01-10T20:28:26.440 に答える
0

非常にハックでバグが発生しやすいアプローチの 1 つは、次回ロードできるようにメモリをファイルに単純にコピーする ac モジュールです。しかし、これが常に適切に機能するとは想像できないので、代わりにピクルスにすることはできますか?

すべてのモジュールを pickle 化できる場合は、globals() ですべてを pickle 化できるはずなので、再度リロードできます。

于 2009-01-10T18:11:07.250 に答える