連載
» 2019年10月04日 05時00分 公開

Python入門:[Python入門]pickleモジュールによるオブジェクトの直列化 (2/2)

[かわさきしんじ,Deep Insider編集部]
前のページへ 1|2       

pickle化できるもの

 pickleモジュールのドキュメントの「pickle 化、非 pickle 化できるもの」には、pickleモジュールを使ってpickle化が可能なオブジェクトが列挙されている。いかにも幾つかを示しておこう。

  • ブール値(True/False)、None値
  • 数値(整数、浮動小数点数など)
  • 文字列、bytesオブジェクト、bytearrayオブジェクト
  • pickle化できるものだけを含んだリスト、タプル、集合、辞書
  • モジュールのトップレベルで定義されている関数、クラス
  • クラスのインスタンス

 これら以外のオブジェクトは、pickle化の対象とはならず、pickle化しようとするとエラーが発生する。pickle化できない代表的なオブジェクトがファイルオブジェクトだ。そこで、これをpickle化してみよう。

myfile = open('mydata.pickle', 'rb')
pickle.dumps(myfile)

ファイルオブジェクトはpickle化できない

 実行結果を以下に示す。

実行結果 実行結果

 このように例外が発生した(ただし、発生する例外は場合によってさまざまだ)。

 また、pickle化できる場合にも制約があることに注意しよう。例えば、関数やクラスをpickle化するというのは「その関数やクラスの名前がpickle化される」ことを意味する。それらの定義を収めたコードがpickle化されるわけではない。例として、関数を定義して、それをpickle化した後、del文で関数を削除してから、非pickle化してみよう。

def hello():
    print('hello world')

pickled_hello = pickle.dumps(hello)
print(pickled_hello)

restored_hello = pickle.loads(pickled_hello)
restored_hello()

del hello

restored_hello = pickle.loads(pickled_hello)

関数を非pickle化するには、それと同じ関数がその環境で定義されている必要がある

 このコードでは、変数pickled_helloにhello関数をpickle化したものを代入している。そして、hello関数が存在している間に一度、変数pickled_helloの値を非pickle化して、その戻り値を変数restored_helloに代入し、それを呼び出している。その後、hello関数を削除してから、もう一度、非pickle化している。

 このコードを実行すると次のようになる。

実行結果 実行結果

 「hello world」という出力結果があるので、restored_hello関数が呼び出されて、問題なく実行できたことが分かる。だが、その後には例外が発生したことを示すメッセージが表示されている。そのメッセージの内容は「__main__モジュールにhelloという属性がない」というものだ。これは現在の対話環境(__main__モジュール)にhello関数がないことを示している。もちろん、del文でhello関数を削除しているのでこれは正しい。つまり、pickle化と非pickle化を行っている環境の両者で、同じ関数が存在しないと、非pickle化は失敗するということだ。

前のページへ 1|2       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。