Pythonのbytes(バイト列)の使い方
- 作成日: 2023-12-24
- 更新日: 2023-12-24
- カテゴリ: Python
Pythonのbytes(バイト列)とは?
Pythonで文字列などの連続したデータを扱う場合、大きく分けて以下の二つがあります。
- str(文字列)
- bytes(バイト列)
文字列というのは一般的によく使われる文字の集まりです。
PythonでHello, World!するときもこの文字列でprint()
を呼び出しています。
バイト列(bytes
)というのは、バイトの集まりのことです。バイトは8ビットで1バイトなのでこの1バイトが連続して並んでいるのがバイト列です。
これはたとえばソケットの通信データや画像のデータを扱う場合などに使われます。
この記事ではこのbytes
について解説していきます。
バイナリシーケンス型 --- bytes, bytearray, memoryview - Python 3.12.1 ドキュメント
関連記事:
Pythonで文字列抽出【インデックスとスライス】
Pythonではこんなに簡単に文字列を検索できます: in演算子, find, reの正規表現
Pythonのstr.find(), str.rfind()の使い方
Pythonで文字列を連結または結合する方法: +演算子、join, format, f文字列など
Pythonの文字列の使い方を簡単にまとめた
Pythonで文字列を置換する具体的な方法(replace, re.sub)
Pythonによる文字列の分割: 区切り文字列、正規表現、改行などによる分割方法を解説
バイト列を得る方法
Pythonでバイト列のデータを定義するのは簡単です。
これはシングルクォートやダブルクォートで囲まれている文字列の先頭にb
というプリフィックスを付けます。
# バイト列の定義
byte_data = b'abc123'
# バイト列を出力
print(byte_data) # b'abc123'
このb
を付けたリテラルを「bytesリテラル」と言います。
バイト列は文字列と同様にインデックスでアクセスしたり、スライスを使って部分を切り取ることができます。
data = b'abc123'
print(data[0]) # 97
print(data[1]) # 98
for b in data:
print(b)
# 97
# 98
# 99
# 49
# 50
# 51
print(data[3:]) # b'123'
上記のようにバイト列の要素はprint()
などで出力すると、数値になっている点に注意してください。
ですのでif文などで要素を比較するときは数値で比較しないといけません。
data = b'abc123'
if data[0] == 97:
print('0 is a')
# 0 is a
もちろんバイト列ごとの比較は以下のようにb
プリフィックスを付けたリテラルで行えます。
data = b'abc123'
if data == b'abc123':
print('true')
# true
bytesリテラルの色々
bytesリテラルは全部で三種類あります。
以下の3つです。
- シングルクォートのbytesリテラル
- ダブルクォートのbytesリテラル
- 3重クォートのbytesリテラル
b'Hello, World!'
b"Hello, World!"
b'''Hello,
World!'''
b"""Hello,
World!"""
この辺は文字列と一緒です。
bytesクラスの使い方
b
プリフィックスの他にはbytes
クラスを使う方法もあります。
イニシャライザは
class bytes([source[, encoding[, errors]]])
のように定義されています。
文字列をsource
にしてencoding
にエンコーディングを指定すると、文字列がバイト列に変換されます。
print(bytes('123', 'utf-8'))
# b'123'
print(bytes('あいう', 'utf-8'))
# b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86'
print(bytes('あいう', 'cp932'))
# b'\x82\xa0\x82\xa2\x82\xa4'
上記では「あいう」のバイト列がエンコーディングutf-8
とcp932
で変わっていることに注目してください。
このようにバイト列はエンコーディングによって表現されるバイトの並びが変わります。
これは、特定のエンコーディングのバイト列は、その特定のエンコーディングで文字列に変換できるということになります。
また、bytes
に数値を直接指定すると、その数の0埋めされた要素数のバイト列を得られます。
print(bytes(10))
# b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
range()
を指定した場合は連番のバイト列を得ることができます。
print(bytes(range(10)))
# b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t'
rプリフィックスによるエスケープシーケンスの無効化
bytesリテラルにはrプリフィックスを付けることができます。
これを付けるとリテラル内のエスケープシーケンスが無効化されます。
# 無効化していない場合
print(b'123\nabc\tdef')
# b'123\nabc\tdef'
# 無効化している場合
print(br'123\nabc\tdef')
# b'123\\nabc\\tdef'
fromhexメソッド
classmethod fromhex(string)
bytes
のメソッドですがこれを使うと16進数の文字列からバイト列を得ることができます。
# 16進数の文字列をバイト列に変換
print(bytes.fromhex('0048 0065 006c 006c 006f'))
# b'\x00H\x00e\x00l\x00l\x00o'
# 文字列にしてみると・・・
print(bytes.fromhex('0048 0065 006c 006c 006f').decode())
# Hello
fromhex()
に渡す文字列の16進数は2桁(0048
など)で指定する必要があります。
hexメソッド
hex([sep[, bytes_per_sep]])
Pythonのバージョン3.5から使えるメソッドです。
バイト列の16進数を文字列にします。
print(b'\xf0\xf1\xf2'.hex())
# f0f1f2
print(bytes.fromhex('0048 0065 006c 006c 006f').hex())
# 00480065006c006c006f
文字列からバイト列に変換する
文字列からバイト列に変換するにはencode()
を使います。
str.encode() — Python 3.12.1 ドキュメント
これはstr
のメソッドとして定義されています。
str.encode(encoding='utf-8', errors='strict')
print('123'.encode()) # b'123'
デフォルトのエンコーディングはUTF-8です。
エンコーディングを変えたい場合はencode()
の引数に指定します。
'123'.encode('cp932')
'123'.encode(encoding='cp932')
errors
の文字列の意味は以下になります。
- 'strict' ... エラー時にUnicodeError例外が送出される
- 'ignore' ... エラー時に無視する
- 'replace' ... エラー時にエラー文字を'?'に置換する
- 'backslashreplace' ... エラー時にエラー文字をバックスラッシュでエスケープされたシーケンスで置換する
バイト列から文字列に変換する
バイト列を文字列に変換したい場合はdecode()
を使います。
bytes.decode() ― Python 3.12.1 ドキュメント
「アル『バイト』のお『でこ』に文字列が光る」で覚えておきましょう。
bytes.decode(encoding='utf-8', errors='strict')
print(b'123'.decode()) # '123'
bytes.decode()
もstr.encode()
と同様にエンコーディングを変更したい場合は引数に指定します。
b'123'.decode('cp932')
b'123'.decode(encoding='cp932')
errors
に指定できる文字列は以下になります。
- 'strict' ... エラー時にUnicodeError例外が送出される
- 'ignore' ... エラー時に無視する
- 'replace' ... エラー時にエラー文字を'?'に置換する
intをbytesに変換する
intをbytesに変換するにはint.to_bytes()
が使えます。
a = 256
print(a.to_bytes(2, 'big')) # バイト数は2バイト。ビッグエンディアン
# b'\x01\x00'
print(a.to_bytes(4, 'little')) # バイト数は4バイト。リトルエンディアン
# b'\x00\x01\x00\x00'
int.to_bytes(length=1, byteorder='big', *, signed=False)
int.to_bytes() — Python 3.12.1 ドキュメント
第1引数のlength
にバイト数を指定し、第2引数のbyteorder
にエンディアンを指定します。
big
がビッグエンディアンで最上位のバイトがバイト列の最初に来ます。
little
がリトルエンディアンで最上位のバイトがバイト列の最後に来ます。
bytesを結合する
bytesの結合は演算子で行います。
bytes同士の結合は+
演算で行えます。
data = b'123' + b'abc'
print(data)
# b'123abc'
data = data + data
print(data)
# b'123abc123abc'
bytesの変数のお尻にbytesを追加で結合したい場合は+=
演算が使えます。
data = b'123'
data += b'abc'
print(data)
# b'123abc'