Pythonで文字列(str型)はUnicode文字を扱いますが、画像ファイル、音声データ、ネットワーク通信のパケットなどを扱う際には、生のバイナリデータが必要になります。
このバイナリデータを表現するために使用されるのが bytes型(バイト列) です。bytes型は、0 から 255 までの整数(1バイト)のシーケンス(並び)であり、一度作成すると変更できない(イミュータブル)という特性を持ちます。
この記事では、bytesオブジェクトの基本的な作成方法と、その特性について解説します。
1. 整数のリストから作成する
bytes() コンストラクタに整数のリストを渡すことで、バイト列を作成できます。リスト内の各整数は、1バイトで表現できる範囲、つまり 0 から 255 の間でなければなりません。
# 0〜255の整数リスト
# 例えば、単純なバイナリパターンやカラーコードなどを想定
binary_values = [10, 20, 128, 255]
# リストをbytes型に変換
data_bytes = bytes(binary_values)
print(f"値: {data_bytes}")
print(f"型: {type(data_bytes)}")
実行結果:
値: b'\n\x14\x80\xff'
型: <class 'bytes'>
出力の見方:
b'...': バイト列であることを示します。\n: ASCIIコードに対応する文字がある場合(10は改行)は、その文字やエスケープシーケンスで表示されます。\x80: ASCII文字に対応しない値は、\xに続く16進数で表示されます。
範囲外の値を指定した場合
リストの中に 256 以上や負の数が含まれていると、ValueError が発生します。
# 範囲外 (256) の値を含むリスト
invalid_values = [0, 100, 256]
# 変換しようとするとエラー
# bytes(invalid_values)
# ValueError: bytes must be in range(0, 256)
2. バイトリテラル (b"...") で作成する
文字列と同じようにクォートで囲み、先頭に b を付けることで、バイト列を直接記述できます。これを「バイトリテラル」と呼びます。
ただし、この記法で記述できるのは ASCII文字(英数字や一部の記号)のみ です。日本語などのマルチバイト文字は直接 b"..." の中には書けません。
# バイトリテラルによる作成
header_signature = b"IMG_HEADER_v1"
print(f"ヘッダー署名: {header_signature}")
# インデックスでアクセスすると、対応する整数の値(文字コード)が返る
print(f"1文字目 ('I') の整数値: {header_signature[0]}")
print(f"2文字目 ('M') の整数値: {header_signature[1]}")
実行結果:
ヘッダー署名: b'IMG_HEADER_v1'
1文字目 ('I') の整数値: 73
2文字目 ('M') の整数値: 77
bytes型の特性:イミュータブル
bytes型は、文字列やタプルと同様に イミュータブル(変更不可能) です。作成後に特定の位置のバイトを書き換えることはできません。
packet_data = b"DATA:1234"
# インデックス指定での書き換えはエラーになる
# packet_data[0] = 65
# TypeError: 'bytes' object does not support item assignment
もし中身を変更可能なバイト列が必要な場合は、bytearray という別の型を使用する必要があります。
まとめ
bytes型は、コンピュータが扱う生のデータ(バイナリ)を表現するための型です。
- 作成方法:
bytes([10, 255, ...]): 0〜255の整数リストから変換。b"ASCII": ASCII文字列から直接作成(バイトリテラル)。
- 特徴:
- 要素は
0から255の整数として管理されます。 - イミュータブルであり、作成後の変更はできません。
- 要素は
ファイル操作やソケット通信など、低レイヤーの処理を行う際に必須となる知識です。
