Msgpack
Table of contents
MessagePack形式はプログラミング言語と独立したデータ構造のバイナリ表現のためのフォーマットで、「JSONのバイナリ版」と考えるとわかりやすい。MessagePack形式へのシリアライズや、シリアライズされたMessagePack形式のバイト列からのデシリアライズがJSONなどと比較して高速に行え、またシリアライズしたときの容量も小さいことから筆者は大量のデータを dict
などの構造のままダンプするときなどに活用している。
PythonでMessagePack形式を扱うには python-msgpack
でパッケージをインストールして利用するのが一般的だろう。 pip install python-msgpack
でインストールできる。
データ構造をMessagePack形式にエンコードする(packする)
msgpack.packb()
を使うことでMessagePack形式にエンコードされたバイト列を得ることができる。
import msgpack
a = dict(
a=1,
b="abc",
c=False,
d=None,
e=[1,2,3],
f={"x": 123, "y": 456, "z": "aiueo"},
g=b'binary string'
)
packed = msgpack.packb(a) # bytes型
データ構造をMessagePack形式にしてファイルに書き込む
msgpack.packb()
した内容をバイナリモードでオープンしたファイルに書き込めばOK
import msgpack
a = dict(a=123, b="abc", c=[1,2,3], d={"x": 123, "y": "yyy"})
packed = msgpack.packb(a)
out_f = "./out.mp"
with open(out_f, "wb") as fh:
# msgpackはバイナリ形式なのでwbモードでオープン
fh.write(packed)
MessagePack形式のバイト列をデコード(unpack)してPythonのデータ構造にする
msgpack.unpackb()
でデコードできる。
import msgpack
# dict(a=123, b="abc", c=[1,2,3], d={"x": 123, "y": "yyy"})
# をmsgpack.packb()したもの
packed = b'\x84\xa1a{\xa1b\xa3abc\xa1c\x93\x01\x02\x03\xa1d\x82\xa1x{\xa1y\xa3yyy'
unpacked = msgpack.unpackb(packed)
MessagePack形式データが書き込まれたファイルを読み込んでPythonのデータ構造にする
バイナリ+読み込みモードでオープンしたファイルからバイナリデータを読み込んで msgpack.unpackb()
でデコードする。
import msgpack
f = "./data.mp"
with open(f, "rb") as fh:
# msgpack形式のデータを読み込む(bytes型)
packed = fh.read()
# Pythonの構造体にunapck
unpacked = msgpack.unpackb(packed)
MessagePackストリーム形式のファイルを作る
MessagePack形式のオブジェクトを続けて書き込むと、後述の Unpacker
でストリームとしてiterableに読み込んで処理できるなど都合がよい。JSON-Lines形式の置き換えなどとしておすすめ。
import msgpack
items = [
{"name": "alice", "age": 23},
{"name": "bob", "age": 24},
{"name": "charlie", "age": 25}
]
f = "./stream.mp"
with open(f, "wb") as fh:
for item in items:
fh.write(msgpack.packb(item))
MessagePackストリーム形式のファイルからデータをイテレーションしながら読み込む
MessagePackストリームを for
文などでイテレートして読み込むには msgpack.Unpacker
クラスを使うとよい。
import msgpack
f = "./stream.mp"
with open(f, "rb") as fh:
unpacker = msgpack.Unpacker(fh)
for item in unpakcer:
print(item)