プログラムの中のデータは、そのままではファイル保存やネットワーク通信に使えません。
そこで必要になるのがシリアライズとデシリアライズです。
本記事では意味と使い方、初心者でも試せる具体例を順番に解説します。
プログラミングでのシリアライズとデシリアライズの意味
シリアライズとは?
シリアライズとは、プログラム内のオブジェクトやデータ構造を、保存や送信に適した連続したデータに変換することです。
日本語では直列化とも言います。
たとえば、Pythonの辞書やJavaScriptのオブジェクトをJSON文字列に変えるのが典型例です。
変換後のデータは文字列(JSONやXMLなど)やバイナリ(bytes)の形になり、ファイルに書き出したりネットワークで送ることができます。
デシリアライズとは?
デシリアライズとは、シリアライズされたデータから元のオブジェクトやデータ構造を復元することです。
JSON文字列を読み取り、プログラムで扱いやすい辞書やオブジェクトに戻す処理がこれに当たります。
これにより、他のプログラムや別のマシンから届いたデータを自分のプログラムで再利用できます。
初心者向けイメージ
データを荷物にたとえると、シリアライズはデータを箱に詰めてラベルを貼る作業、デシリアライズは届いた箱を開けて中身を取り出す作業です。
箱に詰めると運べるようになり、開けるとまた使える形に戻ると考えるとイメージしやすいです。
どこで使う?プログラミングの基本例
ファイル保存でのシリアライズ
アプリの状態やユーザー情報をファイルに保存する際に使います。
たとえばPythonでJSONに保存する例です。
文字コードはUTF-8を明示し、辞書をそのままjson.dumpで書き出すのが基本です。
import json
user = {"name": "Taro", "age": 20, "premium": True}
with open("user.json", "w", encoding="utf-8") as f:
json.dump(user, f, ensure_ascii=False, indent=2) # シリアライズして保存
Web API通信でのシリアライズ
HTTPでデータをやり取りするWeb APIは、JSONを使うのが一般的です。
送信前にJSONに変換し、受信後にJSONを解析してデータ構造へ戻します。
Pythonのrequestsでの例です。
import requests
payload = {"message": "hello", "count": 3}
r = requests.post("https://example.com/api/echo", json=payload) # 自動でJSON化
data = r.json() # レスポンスJSONをデシリアライズ
print(data)
設定データの保存
アプリ起動時に読み込む設定は、人間が読みやすいJSONにしておくと編集しやすいです。
保存する時も読み込む時も同じフォーマットに統一するのがコツです。
# settings.json
# {"theme": "dark", "lang": "ja"}
import json
with open("settings.json", "r", encoding="utf-8") as f:
settings = json.load(f) # デシリアライズ
print(settings["theme"])
小さな例で試す
まずはメモリ内だけで往復させてみましょう。
文字列にしてから元に戻すだけでも、仕組みの流れが理解できます。
import json
original = {"title": "Note", "tags": ["memo", "todo"], "done": False}
s = json.dumps(original, ensure_ascii=False) # シリアライズ(辞書→JSON文字列)
print(type(s), s)
restored = json.loads(s) # デシリアライズ(JSON文字列→辞書)
print(type(restored), restored)
よく使う形式の比較
JSONの特徴
人間が読みやすく、Webと相性が良い標準的な形式です。
文字列中心の軽量フォーマットで、ほとんどの言語に標準ライブラリがあります。
最初の選択肢としておすすめです。
数値や文字列、配列やオブジェクトの表現が得意で、設定ファイルやAPIのデータに向いています。
XMLの特徴
入れ子構造や属性で情報を豊かに表現できます。
スキーマを使って厳格に検証できる点が強みです。
ドキュメント指向や既存のXMLワークフローがある環境で効果を発揮します。
その分、JSONより記述が長くなる傾向があります。
バイナリの特徴
サイズが小さく、読み書きが速いのが利点です。
MessagePackやProtocol Buffersなどが代表例です。
人間が直接読むのには向きませんが、通信量や速度が重要な場面で選ばれます。
形式の選び方の目安
用途や読みやすさ、サイズで選び分けます。
迷ったらまずJSON、速度やサイズが厳しいならバイナリ、文書的表現や既存資産がXMLならXMLという判断で十分です。
| 形式 | 読みやすさ | データサイズ | 相互運用性 | 向いている場面 |
|---|---|---|---|---|
| JSON | 高い | 中 | 非常に高い | Web API、設定、ログ |
| XML | 中 | 中〜大 | 高い | 文書指向、スキーマ検証が必要 |
| バイナリ | 低い | 小 | 中〜高 | 低通信量、高速処理、モバイル通信 |
使い方の手順と注意点
シリアライズの手順
データの形を決め、形式を選び、変換して保存や送信を行います。
基本の流れは次の通りです。
- 保存したい情報を辞書やクラスで表す
- フォーマットを選ぶ(初心者はJSONがおすすめ)
- ライブラリで文字列やバイト列へ変換する
- ファイルへ書く、またはネットワークへ送る
import json
order = {"id": 123, "items": ["pen", "notebook"], "total": 550}
s = json.dumps(order, ensure_ascii=False) # 3. 文字列へ
with open("order.json", "w", encoding="utf-8") as f: # 4. 保存
f.write(s)
デシリアライズの手順
読み込む→文字コードを解釈→解析→必要なら検証の順に進めます。
- 文字列やバイト列を取得する
- 文字コードを適切に扱う(UTF-8推奨)
- ライブラリでデータ構造へ戻す
- 必須項目や型を確認する
import json
with open("order.json", "r", encoding="utf-8") as f:
s = f.read()
order = json.loads(s) # 3. 解析
assert "id" in order and isinstance(order["id"], int) # 4. 簡単な検証
型や項目名をそろえる
JSONのキー名とプログラム側のプロパティ名を一致させるとミスが減ります。
シンプルな辞書でも構いませんが、小さなデータ型を定義するとさらに安全です。
import json
from dataclasses import dataclass
@dataclass
class User:
name: str
age: int
data = json.loads('{"name":"Taro","age":20}')
user = User(**data) # キーが一致していればそのまま作れる
もしJSON側が{“username”: “Taro”}のようにキー名が違うと、そのままでは渡せません。
受け取り側の型と項目名を揃えるか、マッピング処理を入れましょう。
文字コードに注意
ファイルの読み書きはUTF-8を明示するとトラブルが減ります。
OSやエディタの既定値に依存すると文字化けを招くことがあります。
with open("data.json", "w", encoding="utf-8") as f:
f.write('{"title":"こんにちは"}')
with open("data.json", "r", encoding="utf-8") as f:
print(f.read())
信頼できないデータはそのまま読まない
インターネットや外部から来たデータをそのままデシリアライズするのは危険です。
不正なデータで誤作動や情報漏えいを招くことがあります。
JSONなどの安全な形式でも、内容の検証は必要です。
特にpickleや任意コードを実行し得る方式は使わないでください。
- 受け取る形式を限定する(JSONなど)
- サイズや数値範囲、必須項目を検証する
- 使わないフィールドは無視する
エラー時の対処
パースに失敗したら丁寧に例外処理を行い、既定値で復旧できる設計にしておくと安全です。
エラー内容はログに残し、ユーザーには簡潔なメッセージを示します。
import json
from pathlib import Path
DEFAULTS = {"theme": "light", "lang": "ja"}
def load_settings(path="settings.json"):
if not Path(path).exists():
return DEFAULTS.copy()
try:
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
# 足りない項目を既定値で補う
return {**DEFAULTS, **data}
except json.JSONDecodeError as e:
print("[warn] 設定ファイルが壊れています:", e)
return DEFAULTS.copy()
except OSError as e:
print("[warn] ファイルを読み込めません:", e)
return DEFAULTS.copy()
settings = load_settings()
エラーを握りつぶさず、復旧策(既定値や再試行)を用意し、原因調査のためにログへ出力することが大切です。
まとめ
シリアライズはデータを運べる形にする、デシリアライズは元に戻すという2つの動作を押さえれば、ファイル保存やWeb APIなど多くの場面で迷わず使えます。
初心者のうちはJSONとUTF-8に統一し、項目名や型を揃えることを意識するとスムーズです。
さらに信頼できないデータは検証なしで読まない、エラー時は既定値で復旧という基本を守れば、安全で扱いやすいデータ処理が実現できます。
