目次
Python で Protocol Buffers(protobuf) を扱うことになった人向けの記事です。.proto 定義ファイルから生成された *_pb2.py を使って、メッセージの作成・シリアライズ・ファイル/ネットワーク経由のやり取りまで一通り実装する手順をまとめます。あわせて ImportError などハマりがちなエラーの対処も載せます[1]。
Protocol Buffers とは
Protocol Buffers(以下 protobuf)は Google が開発したデータ形式で、JSON や XML より 小さく・速く 構造化データをやり取りできる仕組みです。.proto ファイルにメッセージ定義を書き、専用コンパイラ(protoc)で各言語のコードを生成して使います。Pythonの場合は *_pb2.py というファイルが生成されます。
環境の準備
Python で protobuf を扱うのに必要なものは2つです。
- ランタイムライブラリ(
pip install protobuf) .protoファイルをコンパイルするprotoc(brew install protobuf等)
pip install protobuf
protoc のインストールは macOS なら Homebrew、Linux ならパッケージマネージャ、Windows ならGitHub Releases から取得します[1:1]。
完全なエンドツーエンド例
理解しやすいよう、.proto 定義からPythonでメッセージを使うまでを通して示します。
.proto ファイルを書く
person.proto を作ります。
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
string email = 3;
}
protoc でPythonコードを生成する
protoc --python_out=. person.proto
実行すると person_pb2.py が同じディレクトリに生成されます。
生成された .py をインポートして使う
import person_pb2
# 新しいメッセージインスタンスを作る
person = person_pb2.Person()
person.name = "Alice"
person.age = 30
person.email = "[email protected]"
# シリアライズ(バイト列への変換)
serialized_data = person.SerializeToString()
# 逆シリアライズ(バイト列からの復元)
restored = person_pb2.Person()
restored.ParseFromString(serialized_data)
print(restored.name) # Alice
*_pb2.py を import するだけで、メッセージ型がPythonクラスとして使えるようになります。
ファイルへの読み書き
シリアライズ済みのバイト列をファイルに保存して、後で復元できます。
# 書き込み
with open('person.bin', 'wb') as f:
f.write(person.SerializeToString())
# 読み込み
loaded = person_pb2.Person()
with open('person.bin', 'rb') as f:
loaded.ParseFromString(f.read())
ネットワーク経由での送受信
シリアライズした結果は単なる bytes なので、HTTP・WebSocket・gRPC などお好みの方法で送受信できます。受信側で ParseFromString すれば元のメッセージに戻ります。gRPC を使う場合は protobuf 定義からサーバー/クライアントコードまで一括生成できます。
よくあるエラー
セットアップでつまずきやすい代表的なエラーへの対処です。
ImportError: No module named 'person_pb2'
生成された *_pb2.py がPythonの import パスに無いケース。同じディレクトリに置くか、sys.path に追加します。
import sys
sys.path.append('/path/to/generated')
import person_pb2
TypeError: '...' has type ..., but expected one of: ...
protobuf の型と Python の型が合っていない場合のエラーです。例えば int32 フィールドに文字列を代入すると出ます。.proto の型定義を確認してください。
google.protobuf.message.DecodeError
ParseFromString に渡したバイト列が、対応する protobuf スキーマと一致しないと出ます。よくある原因は次の通りです。
- 別バージョンの
.protoで生成したバイト列を読もうとしている - 文字列をバイト列に変換せず渡している(
b"..."ではなく"...") - ファイルを
'rb'ではなく'r'で開いている
protoc のバージョン違いによる生成コードの差異
protoc のメジャーバージョンが大きく違うと、生成される *_pb2.py の互換性に問題が出ることがあります。チームで開発する場合は protoc のバージョンを揃えてください。
まとめ
Python で protobuf を使う流れは「pip install protobuf + .proto を書く + protoc で *_pb2.py 生成 + import して使う」の4ステップです。エラーの大半は import パス問題 か 型不一致 か バージョン違い に集約されるので、その3点を切り分けると早く解決できます。
参考文献
Protocol Buffers Python Tutorial (2026-05-10 アクセス) ↩︎ ↩︎
