Pythonでネットワーク通信(ソケット通信)やIoT機器とのシリアル通信を行う際、必須となるのが「バイトデータ」の扱いです。
bytes型とbytearray型の基本的な違いや、ファイル操作・暗号化などの基礎的な使い方については、以下の記事で詳しく解説していますので、まずは基礎を押さえたいという方はぜひこちらもご覧ください!
👉 参考記事:Pythonにおけるbytesとbytearrayの完全ガイド:基本から応用まで
上記の記事では「bytearrayは中身が変更可能(ミュータブル)で便利!」という点に触れましたが、実際のシステム開発現場で直面するのは「手元にある文字列(String)や辞書データ(JSON)を、どうやってbytearrayにして送るか?」という具体的なデータ変換の課題です。
本記事では、既存の記事と重複しない「実践的なデータ変換(String/JSON ⇔ bytearray)」にフォーカスし、データ転送時にそのまま使える具体的なテクニックを解説します。
1. なぜデータ転送に「bytearray」が便利なのか?
ネットワーク越しにデータを送る際、Pythonの「文字列」や「辞書データ」をそのまま送信することはできません。すべて「0と1のバイトデータ」に変換(エンコード)する必要があります。
通信プロトコルによっては「先頭の2バイトはデータサイズ」「末尾にチェックサムを追加する」といった細かいパケットの組み立てが求められます。このとき、後から要素を自由に追加・変更(appendやextend)できるbytearrayが圧倒的に扱いやすいのです。
2. 文字列(String)と bytearray の相互変換
テキストメッセージを送信する場合の基本です。文字コード(一般的にはUTF-8)を指定してエンコード・デコードを行います。
String から bytearray への変換(送信時)
# 送信したい文字列
message = "こんにちは、Python通信!"
# 1. 文字列をbytearrayに変換(UTF-8でエンコード)
# ※ bytearray() の第2引数に文字コードを指定します
byte_msg = bytearray(message, "utf-8")
print(type(byte_msg)) # <class 'bytearray'>
print(byte_msg) # bytearray(b'\xe3\x81\x93...')bytearray から String への変換(受信時)
# 受信したbytearrayデータを文字列に戻す
# .decode() メソッドを使用します
received_msg = byte_msg.decode("utf-8")
print(received_msg) # こんにちは、Python通信!3. JSONデータと bytearray の相互変換
Web APIやIoT機器とのやり取りで最も頻出するのがJSON形式です。Pythonの辞書(dict)型データを転送するには、**「辞書 ⇒ JSON文字列 ⇒ bytearray」**という2段階の変換が必要です。
JSON(辞書データ)から bytearray への変換
import json
# 送信したい辞書データ
payload = {
"device_id": "sensor-001",
"temperature": 25.4,
"status": "active"
}
# 1. 辞書(dict)をJSON文字列(str)に変換
# ensure_ascii=False で日本語の文字化けを防ぎます
json_str = json.dumps(payload, ensure_ascii=False)
# 2. JSON文字列をbytearrayに変換
byte_payload = bytearray(json_str, "utf-8")
print(byte_payload)
# 出力例: bytearray(b'{"device_id": "sensor-001", "temperature": 25.4, ...}')bytearray から JSON(辞書データ)への復元
受信側では、全く逆の順番(bytearray ⇒ 文字列 ⇒ 辞書)でデータを復元します。
import json
# 1. 受信した bytearray を文字列(str)にデコード
received_str = byte_payload.decode("utf-8")
# 2. JSON文字列を辞書(dict)に変換
restored_payload = json.loads(received_str)
print(type(restored_payload)) # <class 'dict'>
print(restored_payload["temperature"]) # 25.44. 【応用】数値データをそのままbytearrayに埋め込む(structモジュールの活用)
JSONは便利ですが、データサイズが大きくなりがちです。通信帯域が限られている組み込み機器(Raspberry Piやマイコンなど)とのシリアル通信では、「C言語の構造体」のように、数値(intやfloat)を直接バイト列として詰め込む手法がよく使われます。
これをPythonで実現するには、標準ライブラリの struct モジュールと bytearray を組み合わせます。
import struct
# 例:デバイスID(整数:4バイト) と 温度(浮動小数点:4バイト) を送る
device_id = 101
temperature = 25.4
# 'i'は4バイト整数、'f'は4バイト浮動小数点を意味するフォーマット文字
# struct.pack で bytes型が生成される
packed_data = struct.pack('if', device_id, temperature)
# bytesをbytearrayに変換して、後からヘッダー情報などを追加可能にする
packet = bytearray(packed_data)
# ヘッダーとしてパケットの先頭に特定の識別子(例: 0xFF)を追加
packet.insert(0, 0xFF)
print(packet) # bytearray(b'\xffe\x00\x00\x00\xcd\xcc\xcbA')このように、用途に合わせてデータを柔軟にパッキングできるのが bytearray の真骨頂です。
まとめ
この記事では、データ転送の実務で欠かせない bytearray を使ったデータ変換テクニックを解説しました。
- 基礎知識:
bytesとbytearrayの違いや基本的な操作はこちらの基礎解説記事を参照。 - 文字列の変換:
bytearray(text, "utf-8")と.decode("utf-8")でシンプルに変換可能。 - JSONの変換:
json.dumps()/json.loads()を経由して、辞書データとバイト列を相互変換する。 - バイナリ変換: 通信帯域を節約したい場合は
structモジュールを組み合わせて直接数値をバイト化する。
ネットワーク通信やシリアル通信のプログラムでは、文字列、JSON、バイナリが入り乱れます。今自分が扱っている変数が「String」なのか「bytearray」なのかをしっかり意識し、適切な変換処理を実装してみてください!


コメント