1. 背景説明
Pythonでシミュレーションを行ったのですが、シミュレーション時間が割と長かったので、途中のデータを見たいときに再度実行する必要があるので、これらのデータをすべて保存してロードする方法を考えました。見たいときに。
ここで最初に思いついたのは json でしたが、JSON ではできないことや非常に面倒なことがあることがわかり、再び pickle を見つけました。
2.JSON
JSON は軽量のデータ交換形式であり、JavaScript のサブセットです。もともと、このデータ形式は xml を置き換えるために使用されていましたが、現在ではそれができることが基本的に証明されています。使用方法は次のとおりです。
2.1. Python オブジェクトを JSON 文字列に変換する
このタスクを実行するには、ダンプとダンプという 2 つの方法があります。
まずダンプを紹介します。
import json
data = {
'a': 1, 'b': 'name'}
str = json.dumps(data)
print(str)
Python オブジェクトを文字列にシリアル化します。
次に、ダンプを導入します。
import json
data = {
'a': 1, 'b': 'name'}
with open('data.json','wb') as f:
json.dump(data,f)
Python オブジェクトをシリアル化してファイルに書き込みます。
違い: 2 つの違いは、1 つは文字列にシリアル化され、もう 1 つはファイルにシリアル化され、ダンプ内の余分な s は文字列と見なすことができます。
2.2. JSON文字列をPythonオブジェクトに変換する
上記の内容とは異なり、load と load という 2 つのインターフェイスもありますが、賢明な読者なら、1 つは文字列の逆シリアル化で、もう 1 つはファイルの逆シリアル化であることはすでに推測されています。
import json
data = json.loads(str)
print(data)
import json
with open('data.json', 'rb') as f:
data = json.load(f)
2.3、カスタム JSON デコーダーとエンコーダー
JSON エンコーダーとデコーダーは、json.JSONEncoder
およびクラスを継承することでカスタマイズできます。json.JSONDecoder
import json
# 自定义 JSON 编码器
class PersonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Person):
return {
'name': obj.name, 'age': obj.age}
return super().default(obj)
# 自定义 JSON 解码器
class PersonDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
super().__init__(object_hook=self.object_hook, *args, **kwargs)
def object_hook(self, dct):
if 'name' in dct and 'age' in dct:
return Person(dct['name'], dct['age'])
return dct
# 定义 Person 类
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# 使用自定义编码器和解码器
data = [Person('Alice', 25), Person('Bob', 30)]
json_str = json.dumps(data, cls=PersonEncoder)
data = json.loads(json_str, cls=PersonDecoder)
ただし、この定義方法は煩雑であり、依然として非常に複雑なデータを処理することはできず、より複雑なデータの処理方法を提供するだけです。詳細には立ち入りません(私も入りません)。
3、漬物
Pickle は、上記の 4 つのメソッドdump
、dumps
、load
、のいずれかを提供しますloads
。違いは同じです。詳細には触れませんが、ここではシリアル化メソッドを示します。
import numpy as np
import pickle
# 定义包含 NumPy 数组的 Python 对象
class DataObject:
def __init__(self):
self.array = np.zeros(100,dtype='float64')
self.age = 0
self.name = 'name'
def reset(self):
self.age = 100
self.name = 'ale'
data = DataObject();
# 序列化对象到文件
with open('serialized_data.pkl', 'wb') as file:
pickle.dump(data, file)
with open('serialized_data.pkl', 'rb') as file:
data2 = pickle.load(file)
data2.reset()
print(data2.array)
print(data2.age)
print(data2.name)
上記のプログラムを実行すると、シリアル化と逆シリアル化が実行できることがわかりましたが、両者の長所と短所は何でしょうか?
4、メリットとデメリット
pickle
利点:
- カスタム クラス、関数、複数のオブジェクト間の参照関係を含む、ほぼすべての Python オブジェクトのシリアル化をサポートします。
- オブジェクトの状態、メソッド、クラス情報などを保存し、デシリアライズ後にオブジェクトの元の構造を完全に復元できます。
- シリアル化と逆シリアル化のプロセスは比較的単純で、 メソッド
dump()
とload()
メソッドを呼び出すだけです。
pickle
短所:
pickle
は Python 固有の形式であるため、言語を超えて使用することはできません。pickle
他のプログラミング言語では、生成されたデータを正しく解析できない場合があります。pickle
生成されたシリアル化されたデータは通常大きく、多くのストレージ容量を消費します。
json
利点:
json
これは一般的なデータ交換形式であり、ほとんどすべてのプログラミング言語が JSON 形式でのデータの解析と生成をサポートしています。- 生成される JSON データは比較的小さく、ストレージ容量の消費も比較的少なくなります。
- 人間が読みやすく、理解しやすく、デバッグしやすい。
json
短所:
- 辞書、リスト、文字列、数値などの基本型など、一部の単純なデータ型のみをシリアル化できます。また、カスタムの複雑なオブジェクトや関数のシリアル化はサポートされていません。
- データの値のみを保存でき、オブジェクトの状態、メソッド、クラス情報は失われます。