Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonオブジェクトのシリアライズ完全ガイド:pickleモジュールの基本とJSONとの違い

シリアライズ(直列化)とは?

シリアライズとは、オブジェクトをファイルやメモリバッファなどに保存・格納できる形式へと変換するプロセスのことです。一度シリアライズしておけば、後から元の形式に復元(デシリアライズ)し、元のオブジェクトやデータをそのまま取り出すことができます。Pythonでは、この一連の操作を標準ライブラリの pickle モジュールで簡単に行うことができます。

ピクル化(Pickling)とは

Pythonのpickleモジュールは、Pythonのオブジェクト構造をシリアライズ(直列化)およびデシリアライズ(復元)するためのものです。リストや辞書など、あらゆる種類のPythonオブジェクトをバイトストリーム(0と1の並び)に変換するこの処理は、「ピクル化」「シリアライズ」「フラット化」「マーシャリング」などと呼ばれます。逆に、ピクル化によって生成されたバイトストリームを再びPythonオブジェクトへ戻す操作は「アンピクル化(unpickling)」と呼ばれます。

オブジェクトをピクル化する手順は非常にシンプルで、以下の2ステップだけです。

  • pickleモジュールをインポートする
  • dumps() 関数を呼び出す
import pickle
class Vehicle:
    def __init__(self, number_of_doors, color):
        self.number_of_doors = number_of_doors
        self.color = color
class Car(Vehicle):
    def __init__(self, color):
        Vehicle.__init__(self, 5, color)
Maruti = Car('Red')
print(str.format('My Vehicle Maruti is {0} and has {1} doors', Maruti.color, Maruti.number_of_doors))
pickle_Maruti = pickle.dumps(Maruti)
print('Here is my pickled Vehicle: ')
print(pickle_Maruti)

実行結果

My Vehicle Maruti is Red and has 5 doors
Here is my pickled Vehicle:
b'\x80\x03c__main__\nCar\nq\x00)\x81q\x01}q\x02(X\x0f\x00\x00\x00number_of_doorsq\x03K\x05X\x05\x00\x00\x00colorq\x04X\x03\x00\x00\x00Redq\x05ub.'

上記の例では、Carクラスのインスタンスを作成し、それをピクル化することで、車のインスタンスを単純なバイト配列へと変換しています。一度ピクル化してしまえば、そのデータをバイナリファイルやデータベースのフィールドに簡単に保存でき、後から読み込んでバイト列を元のオブジェクト階層へと復元することが可能です。

補足: ピクル化したオブジェクトをファイルとして作成したい場合は、dumps() メソッドではなく dump() メソッドを使用します。

アンピクル化(Unpickling)

アンピクル化はピクル化の逆の操作であり、バイナリストリームを受け取ってオブジェクト階層へと変換する処理です。

復元にはpickleモジュールの load() 関数を使用します。この関数は、バイトストリームから完全なオブジェクト階層を返します。

以下は load の使用例です。

import pickle
class Vehicle:
    def __init__(self, number_of_doors, color):
        self.number_of_doors = number_of_doors
        self.color = color
class Car(Vehicle):
    def __init__(self, color):
        Vehicle.__init__(self, 5, color)
Maruti = Car('Red')
print(str.format('My Vehicle Maruti is {0} and has {1} doors', Maruti.color, Maruti.number_of_doors))
pickle_Maruti = pickle.dumps(Maruti)
# Marutiをアンピクル化して別のインスタンス Hyundai を作成
Hyundai = pickle.loads(pickle_Maruti)
# 新しいインスタンスの色を変更
Hyundai.color = 'Black'
print(str.format("Hyundai is {0} ", Hyundai.color))
print(str.format("Maruti is {0} ", Maruti.color))

この例では、最初に車オブジェクト(Maruti)をピクル化し、その後それを別の変数(Hyundai)へアンピクル化しています。つまり、ある意味でMarutiを「クローン」してHyundaiを作り出したことになります。

実行結果

My Vehicle Maruti is Red and has 5 doors
Hyundai is Black
Maruti is Red

PickleとJSONの比較

JSON(JavaScript Object Notation)は、軽量なデータ交換フォーマットであり、人間が読みやすいのが特徴です。pickleに対するJSONの大きな利点の一つは、標準化されており言語に依存しない点です。また、pickleよりも安全で高速に動作します。

もう一つのpickleの代替手段が cPickle です。cPickleはpickleとほぼ同じですが、C言語で実装されており、約1000倍高速という特徴があります。pickle用に書かれたファイルはcPickleでもそのまま使用できます。

import json
mylist = [2, 4, 5, "ab", "cd", "ef"]
print("Here is my list: ", mylist)
json_string = json.dumps(mylist)
print("Here is my json encoded object: ", json_string)
print("Here is JSON back to a data structure: ", json.loads(json_string))

実行結果

Here is my list: [2, 4, 5, 'ab', 'cd', 'ef']
Here is my json encoded object: [2, 4, 5, "ab", "cd", "ef"]
Here is JSON back to a data structure: [2, 4, 5, 'ab', 'cd', 'ef']

上記のコードでは、まずオブジェクト(リスト)に対して dumps メソッドを使って文字列を取得し、次に loads メソッドを使ってJSON文字列を再びデータ構造(JSONオブジェクト)へと復元しています。

  1. Pythonのオブジェクト比較を徹底解説:「is」と「==」演算子の違い

    本記事では、Pythonにおけるオブジェクト比較の方法として、「is」演算子と等価演算子「==」の違いについて詳しく解説します。 この2つの演算子は似ているようで、実はまったく異なる役割を持っています。それぞれの動作の仕組みを正しく理解することは、バグの少ないPythonコードを書く上で非常に重要です。 「==」と「is」の基本的な違い 等価演算子(==)は、渡されたオブジェクトの値が等しいかどうかを判定します。つまり、2つのオブジェクトがメモリ上のどこに格納されていようと、中身の内容が同じであれば「等しい」とみなされます。 一方、is 演算子は、2つのオブジェクトが同一の参照(同じメモリ上の

  2. Pythonのtimetuple()メソッドとは?struct_timeオブジェクトの基本と使い方

    Pythonでは、datetime.dateインスタンスが持つtimetuple()メソッドを呼び出すと、time.struct_time型のオブジェクトが返されます。struct_timeは名前付きタプル(named tuple)の一種で、インデックス番号だけでなく、属性名を使って各フィールドにアクセスできるのが特徴です。struct_timeオブジェクトの構成要素struct_timeオブジェクトには、日付と時刻の両方を表す属性が含まれており、さらに夏時間(DST:Daylight Saving Time)が有効かどうかを示すフラグも持っています。timetuple()関数が返す名前付きタ