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 をいじる代償です。