シリアライゼーション (pickleモジュール) について

プログラムを実行して得られたデータやオブジェクトの状態を保存し、後で再利用したい場面がよくあります。例えば、機械学習モデルや設定ファイルのオブジェクトをファイルに保存して、次回のプログラム実行時に再利用することは非常に便利です。このような操作を簡単に行うために、Pythonにはpickleモジュールが用意されています。 この記事では、Pythonpickleモジュールを使ったシリアライゼーション(直列化)とデシリアライゼーション(逆直列化)について詳しく解説します

シリアライゼーションとは?

シリアライゼーションとは、Pythonのオブジェクト(リスト、辞書、カスタムクラスなど)をバイナリデータに変換し、そのデータをファイルやネットワークを通じて保存したり送信したりできる形式に変換するプロセスです。一方、シリアライズされたデータを元のオブジェクトに復元することをデシリアライゼーションと呼びます。 Pythonでは、シリアライゼーションにpickleモジュールを使用します。pickleを使うと、Pythonのオブジェクトをそのままファイルに保存し、後で同じ状態で読み込むことができます

pickleモジュールの基本的な使い方

まずは、pickleモジュールの基本的な操作、すなわちシリアライゼーションとデシリアライゼーションの方法を見ていきます。

シリアライゼーション(オブジェクトの保存)

以下は、Pythonのリストオブジェクトをpickleを使ってファイルに保存する例です。

import pickle
# 保存するオブジェクト
data = {'name': 'Alice', 'age': 25, 'scores': [85, 90, 88]}
# ファイルにシリアライズして保存
with open('data.pkl', 'wb') as file:
    pickle.dump(data, file)
print("データが保存されました")
  • dump(): このメソッドを使って、オブジェクトをバイナリ形式でファイルに書き込みます。ファイルはバイナリモード(wb)で開く必要があります。

デシリアライゼーション(オブジェクトの読み込み)

次に、先ほど保存したファイルからデータを読み込み、元のオブジェクトに復元する例です。

import pickle
# ファイルからデータをデシリアライズして読み込み
with open('data.pkl', 'rb') as file:
    loaded_data = pickle.load(file)
print("読み込まれたデータ:", loaded_data)
  • load(): ファイルからバイナリ形式のデータを読み込み、元のオブジェクトに復元します。ファイルは読み込みバイナリモード(rb)で開きます。

実行結果

データが保存されました
読み込まれたデータ: {'name': 'Alice', 'age': 25, 'scores': [85, 90, 88]}

pickleの応用

pickleモジュールを使うと、基本的なデータ構造以外にも、カスタムクラスや関数など、さまざまなPythonオブジェクトをシリアライズできます。

カスタムクラスのシリアライゼーション

次に、カスタムクラスのオブジェクトをシリアライズして保存し、後で復元する例を見てみましょう。

import pickle
# カスタムクラス
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def greet(self):
        return f"Hello, my name is {self.name}."
# Personオブジェクトを作成
person = Person("Bob", 30)
# ファイルにシリアライズして保存
with open('person.pkl', 'wb') as file:
    pickle.dump(person, file)
# ファイルから読み込み
with open('person.pkl', 'rb') as file:
    loaded_person = pickle.load(file)
print(loaded_person.greet())  # -> Hello, my name is Bob.

複数のオブジェクトをシリアライズ

pickleを使って、複数のオブジェクトをファイルにまとめて保存することも可能です。

import pickle
data1 = {'name': 'Alice', 'age': 25}
data2 = [1, 2, 3, 4, 5]
# 複数のオブジェクトをファイルに保存
with open('multiple.pkl', 'wb') as file:
    pickle.dump(data1, file)
    pickle.dump(data2, file)
# ファイルから複数のオブジェクトを読み込み
with open('multiple.pkl', 'rb') as file:
    loaded_data1 = pickle.load(file)
    loaded_data2 = pickle.load(file)
print(loaded_data1)  # -> {'name': 'Alice', 'age': 25}
print(loaded_data2)  # -> [1, 2, 3, 4, 5]

pickleの利点と欠点

pickleモジュールは非常に便利ですが、その使用にはいくつかの利点と注意点があります。

利点

  • Pythonオブジェクトを簡単に保存・復元: 複雑なデータ構造やカスタムオブジェクトを簡単にファイルに保存し、後で同じ状態で再利用できます。
  • 標準ライブラリに含まれている: picklePythonの標準ライブラリに含まれているため、追加のインストールなしで使用可能です。

欠点と注意点

  • セキュリティのリスク: pickleされたデータは、Pythonオブジェクトをそのまま復元するため、不正なデータが渡された場合に悪意あるコードが実行される可能性があります。そのため、信頼できないデータのデシリアライゼーションには注意が必要です。外部から受け取ったデータをpickleで読み込むことは避けるべきです。

  • Python専用フォーマット: picklePython専用のバイナリフォーマットを使っており、他のプログラミング言語では直接利用できません。異なる言語間でデータをやり取りする場合には、JSONXMLのような標準的なフォ ーマットを使用する必要があります。

pickleの代替手段

Pythonにはpickle以外にも、データを保存・読み込みするための方法がいくつかあります。データの用途やフォーマットによって、これらの方法も選択肢に含めるべきです。

jsonモジュール

jsonモジュールは、データをJSON形式で保存・読み込みでき、他のプログラミング言語やWebアプリケーションとのデータ交換に適しています。

import json
data = {'name': 'Alice', 'age': 25}
# JSON形式で保存
with open('data.json', 'w') as file:
    json.dump(data, file)
# JSON形式で読み込み
with open('data.json', 'r') as file:
    loaded_data = json.load(file)
print(loaded_data)  # -> {'name': 'Alice', 'age': 25}

shelveモジュール

shelveは、pickleを使ってデータを保存しますが、ディスク上で辞書のようにアクセス可能なデータベースとして使用できる便利なモジュールです。

import shelve
with shelve.open('mydata') as db:
    db['person'] = {'name': 'Alice', 'age': 25}
with shelve.open('mydata') as db:
    print(db['person'])  # -> {'name': 'Alice', 'age': 25}

まとめ

pickleモジュールは、Pythonのオブジェクトをシリアライズして保存し、後でその状態を復元するための非常に便利なツールです。リストや辞書、カスタムオブジェクトなどを簡単に保存・復元できるため、プログラムの実行結果を再利用したり、一時的なデータを保存する用途に適しています。

  • シリアライゼーションを使ってデータを保存
  • デシリアライゼーションを使ってデータを復元
  • カスタムクラスや複雑なオブジェクトも保存可能 ただし、pickleは信頼できるデータのみを扱うようにし、不正なデータに対しては十分に注意を払う必要があります。