1. ホーム
  2. python

Python シェルでクラスを再読み込みする方法は?

2023-07-27 18:59:49

質問

あるパッケージに属する同名のクラスを定義したモジュールをインポートすると、親パッケージの__init__.pyにより、モジュールではなくクラスとしてインポートされます。参照 ディレクトリが異なるとインポート結果が異なる を参照してください。Pythonシェルやipythonシェルで、もし私が

from MyPak import MyMod

MyModuleは常にClassとしてインポートされるため、リロードすることができません(reload()はモジュールに対してのみ機能します)。実行する

from MyPak import MyMod

は、クラス定義を更新しないようです。誰か、Pythonシェルでクラスを更新する方法を教えてください。

ps. pythonインタプリタを再起動することなく。

pps . 念のため、手元にあるコードでテストしてみたいと思います。私は実際にBioPythonについて話しており、Bio.PDB.PDBParserに取り組んでいます。ipythonシェル(v0.10)を使ってPDBParser.pyを編集しています。ただ、ipythonでそれを再読み込みする方法がありません。

というわけで、私がやったことは以下の通りです。

# start ipython v0.10
import Bio
from Bio.PDB import PDBParser
p = PDBParser()
s = p.get_structure()
# then I make changes,e.g. simply print some text, in PDBParser.py
del Bio
del PDBParser
del s
import Bio  # or reload(Bio) without deleting all the objects
from Bio.PDB import PDBParser
p = PDBParser()
s = p.get_structure() # expected output after change not seen :(

印刷されたテキストを見ることができませんでした。何らかの原因で変更が適用されなかったのです。

どうすればよいのでしょうか。

やっと答えが見つかりました。

import MyPak
from MyPak import MyMod

編集後 MyPak/MyMod.py ファイルを再読み込みすると、クラス MyMod をファイル MyMod.py を作成する必要があります。

import sys
del sys.modules['MyPak.MyMod'] 
reload(MyPak)
from MyPak import MyMod

注意事項 :

  1. 実行中 del MyPak または del MyMod または del MyPak.MyMod は、単に名前バインディングを削除するだけなので、問題は解決しません。Python が検索するのは sys.modules を検索して、モジュールが既にインポートされているかどうかを確認するだけです。ポストでの議論をチェックアウト モジュール名が sys.modules と globals() の中で .

  2. MyPakをリロードするとき、pythonは次の行を実行しようとします。 from MyMod import MyModMyPak/__init__.py . しかし、それは MyPak.MyModsys.modules であるため ではない リロード MyMod ただし MyPak/MyMod.py は更新されています。そして、新しい MyPak/MyMod.pyc は生成されません。