Select Language

AI Technology Community

4.9、Python pickleモジュールの使用方法

シリアライズは主にネットワーク伝送や永続化に用いられます。私たちは、ネットワーク上のデータはすべてバイトストリームであることを知っています。あるオブジェクトを遠隔のマシンに送信したい場合、まずそれをバイトストリームに変換しなければならず、その後で初めてネットワーク上で伝送することができます。ファイルもバイトストリームです。あるオブジェクトをファイルに保存したい場合も、まずそれをバイトストリームに変換しなければならず、その後で初めて保存することができます。

シリアライズに対応するのはデシリアライズです。つまり、バイトストリームから元のオブジェクトを復元することです。こうすることで、伝送に意味が生まれます。

基本的な流れ

シリアライズとデシリアライズをネットワーク伝送と組み合わせると、図1に示すようなプロセスを得ることができます。


図1 シリアライズとデシリアライズ


データをファイルに永久保存またはバックアップする場合は、図6 - 2でそのプロセスを表すことができます。


図2 オブジェクトの保存プロセス


シリアライズはこれら2つの分野で非常に有用であることがわかります。シリアライズの基本的な要求は、復元されたオブジェクトが元のオブジェクトと等価であり、情報の損失がないことです。

pickleの使い方

シリアライズに関連するモジュールはたくさんあり、例えばpickle、cpickle、json、marshalなどがあります。これらはすべて変換効率や圧縮効率に力を入れていますが、基本的な機能はほぼ同じです。そのため、このチュートリアルではこれらのモジュールをすべて詳細に説明することはせず、主にpickleライブラリの使い方を説明します。

pickleはインストールする必要はありません。これはPythonに付属しているパッケージであり、使用する際には単にこのパッケージをインポートするだけです。方法は次の通りです。

import pickle

pickleパッケージは主に2つの機能を提供しています。1つはオブジェクトをバイトストリームに変換する、つまりシリアライズする機能です。もう1つはバイトストリームをオブジェクトに変換する、つまりデシリアライズする機能です。それぞれの機能には2つの分岐があり、1つは単にバイトストリームに変換するもので、もう1つはバイトストリームに変換してファイルに保存するものです。そのため、pickleパッケージには主に4つのインターフェースがあり、表3に示す通りです。

表3 pickleパッケージの主なインターフェース シリアライズ
操作シリアライズデシリアライズ
変換+ファイル操作dump()load()
変換dumps()loads()

1) dump(オブジェクト, ファイルオブジェクト):シリアライズしてファイルに保存

dumpのファイルオブジェクトは書き込み可能である必要があります。

>>> a = range(10)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> fd = open("tmp,bin", "wb")
>>> fd
<open file 'tmp,bin', mode 'wb' at 0x0000000000277E8A0>
>>> pickle.dump(a, fd)
>>> fd.close()
>>> fd2 = open("tmp,bin", "rb")
>>> a2 = pickle.load(fd2)
>>> a2
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

2) load(ファイルオブジェクト):ファイルからデータを読み出してオブジェクトを復元

load関数はファイルオブジェクトからオブジェクトを読み出し、返り値はそのオブジェクトです。上の例ではこのインターフェース関数の使い方を示しました。

3) dumps(オブジェクト):単にシリアライズする

dumps関数はバイトストリームを返します。

>>> a = range(10)>>> a[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>>> s = pickle.dumps(a)>>> s's(lp0\nI0\naI1\naI2\naI3\naI4\naI5\naI6\naI7\naI8\naI9\na.<'>>> type(s)<type 'str'>>>> b = pickle.loads(s)>>> b[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

4) loads(バイトストリーム):バイトストリームからオブジェクトを復元

入力はdumps()の返り値である必要があります。注意してください。バイトストリームを勝手に構築しないでください。すべてのバイトストリームが解析できるわけではありません。このインターフェース関数の使い方は上の例ですでに示されています。

また、複数のオブジェクトを1つのファイルに保存することはできますか?答えはできます。複数のオブジェクトを書き込む必要がある場合は、dump()関数を複数回呼び出すことができます。同様に、復元する際にもload()関数を複数回呼び出す必要があります。それらの対応関係は、最初のload()で得られるオブジェクトは最初のdump()に対応するオブジェクトであり、2回目のload()で得られるオブジェクトは2回目のdump()に対応するオブジェクトです。簡単に言えば、先入れ先出しです。

以下のコードでこの使い方を示します。

>>> a1 = range(3)
>>> a1
[0, 1, 2]
>>> a2 = range(5)
>>> a2
[0, 1, 2, 3, 4]
>>> fd = open("tmp,bin", "wb")
>>> pickle.dump(a1, fd) # まず短いリストを書き込む
>>> pickle.dump(a2, fd) # 次に長いリストを書き込む
>>> fd.close()
>>> fd2 = open("tmp,bin", "rb")
>>> b1 = pickle.load(fd2)
>>> b1 # 最初に読み出されるのは短いリスト
[0, 1, 2]
>>> b2 = pickle.load(fd2)
>>> b2 # 次に読み出されるのは長いリスト
[0, 1, 2, 3, 4]
>>> fd2.close()


post
  • 10

    item of content
Pythonにおいて、ディレクトリとファイルは非常に重要で、異なるファイルでは同じ関数や変数を定義しても衝突が起こりません。これはJavaに似ており、CやC++とは明らかに異なります。Pythonはソースコードのレベルでネームスペースを定義していないため、ファイルとパスがimport文と共にネームスペースの役割を果たします。
異なるPythonファイルは異なるモジュールに対応し、同じディレクトリ内の複数のPythonファイルの集合が1つのパッケージとなります。
この章では、読者にPythonのモジュールとパッケージの概念と定義を説明し、合わせてサードパーティのPythonパッケージの様々なインストール方法と使用法を紹介します。