MyClass
で定義されたクラスがありmy_module
ます。問題のクラスのインスタンスをピクルMyClass
するメソッドがあります。pickle_myself
def pickle_myself(self, pkl_file_path):
with open(pkl_file_path, 'w+') as f:
pkl.dump(self, f, protocol=2)
にあることを確認しmy_module
ましたPYTHONPATH
。インタープリターでは、実行は正常に__import__('my_module')
機能します。
>>> __import__('my_module')
<module 'my_module' from 'A:\my_stuff\my_module.pyc'>
ただし、最終的にファイルをロードすると、次のようになります。
File "A:\Anaconda\lib\pickle.py", line 1128, in find_class
__import__(module)
ImportError: No module named my_module
私が確認したいくつかのこと:
の場所を変更していません
my_module.py
(モジュールのディレクトリを変更した後の Python pickling )代わりに使用しようとしまし
dill
たが、それでも同じエラーが発生します( python ImportError の詳細 No module named )
編集 - エラーを再現するおもちゃの例:
例自体は、多数のファイルに分散しています。
まず、モジュールがありますball
( というファイルに保存されていますball.py
):
class Ball():
def __init__(self, ball_radius):
self.ball_radius = ball_radius
def say_hello(self):
print "Hi, I'm a ball with radius {}!".format(self.ball_radius)
次に、モジュールがありますtest_environment
:
import os
import ball
#import dill as pkl
import pickle as pkl
class Environment():
def __init__(self, store_dir, num_balls, default_ball_radius):
self.store_dir = store_dir
self.balls_in_environment = [ball.Ball(default_ball_radius) for x in range(num_balls)]
def persist(self):
pkl_file_path = os.path.join(self.store_dir, "test_stored_env.pkl")
with open(pkl_file_path, 'w+') as f:
pkl.dump(self, f, protocol=2)
次に、環境を作成し、永続化し、ロードするための関数を含むモジュールを用意しましたmake_persist_load
。
import os
import test_environment
#import pickle as pkl
import dill as pkl
def make_env_and_persist():
cwd = os.getcwd()
my_env = test_environment.Environment(cwd, 5, 5)
my_env.persist()
def load_env(store_path):
stored_env = None
with open(store_path, 'rb') as pkl_f:
stored_env = pkl.load(pkl_f)
return stored_env
次に、すべてをまとめるスクリプトを次のように作成しますtest_serialization.py
。
import os
import make_persist_load
MAKE_AND_PERSIST = True
LOAD = (not MAKE_AND_PERSIST)
cwd = os.getcwd()
store_path = os.path.join(cwd, "test_stored_env.pkl")
if MAKE_AND_PERSIST == True:
make_persist_load.make_env_and_persist()
if LOAD == True:
loaded_env = make_persist_load.load_env(store_path)
このおもちゃの例を簡単に使用できるようにするために、すべてを Github リポジトリに配置しました。このリポジトリは、選択したディレクトリに複製するだけで済みます。. 含まれている手順を参照してくださいREADME
。これもここに複製します。
指示:
1) リポジトリをディレクトリにクローンします。
2) リポジトリ ディレクトリを PYTHONPATH に追加します。
3) を開きtest_serialization.py
、変数MAKE_AND_PERSIST
を に設定しますTrue
。インタープリターでスクリプトを実行します。
4) 以前のインタプリタ インスタンスを閉じて、新しいインタプリタ インスタンスを起動します。でにtest_serialization.py
変更MAKE_AND_PERSIST
するFalse
と、これはプログラムで に設定さLOAD
れTrue
ます。スクリプトをインタープリターで実行すると、ImportError: No module named test_environment
.
5) デフォルトでは、ピクルスの代わりにディルを使用するようにテストが設定されています。これを変更するには、 および に進みtest_environment.py
、make_persist_load.py
必要に応じてインポートを変更します。
編集: dill '0.2.5.dev0' に切り替えた後、dill.detect.trace(True)
出力
C2: test_environment.Environment
# C2
D2: <dict object at 0x000000000A9BDAE8>
C2: ball.Ball
# C2
D2: <dict object at 0x000000000AA25048>
# D2
D2: <dict object at 0x000000000AA25268>
# D2
D2: <dict object at 0x000000000A9BD598>
# D2
D2: <dict object at 0x000000000A9BD9D8>
# D2
D2: <dict object at 0x000000000A9B0BF8>
# D2
# D2
編集:おもちゃの例は、Mac/Ubuntu (つまり、Unix のようなシステム?) で実行すると完全に機能します。Windows でのみ失敗します。