Python 3の登場により、bytes型はバイナリデータを保存して処理するための基本型となり、文字列(str)から分離されました。Python 2では、文字列(str)はテキストとバイトの両方を含むことができましたが、これが異なるエンコーディングでのデータ処理時に頻繁にエラーを引き起こしました。
日常的なプログラミングでは、テキスト情報の文脈外でデータを転送・保存するという課題にしばしば直面します。たとえば、ファイル、ネットワークリクエスト、交換プロトコルの操作が該当します。このため、バイト列を文字列データから明確に区別する、明示的で便利かつ安全な型が必要です。
Pythonのbytes型は、変更不可能なバイト列(0から255までの整数)のシーケンスを保持し、バイトリテラル(接頭辞b付き)から作成するか、明示的な型変換を通じて生成できます。文字列(str)とバイト(bytes)間の安全で予測可能な相互作用には、.encode()と.decode()メソッドが使用されます。ファイル、ネットワーク、およびさまざまなバイナリプロトコルを操作する際には、bytesが主な選択肢となります。
コード例:
# bytesオブジェクトの作成 b = b'hello' # リテラルを使用して b2 = bytes([104, 101, 108, 108, 111]) # 整数リストから # str <=> bytesの変換 text = 'テキスト' bin_text = text.encode('utf-8') # str -> bytes back = bin_text.decode('utf-8') # bytes -> str # ファイルの例 with open('file.bin', 'rb') as f: data = f.read() # data: bytes
主な特徴:
bytesとstrを同じ変数に連結できますか?
いいえ、+での連結やf文字列では動作しません。b'abc' + 'def'を実行しようとするとTypeErrorが発生します。型を明示的に変換する必要があります。
bytesとbytearrayの違いは何ですか?
bytesは変更不可能な型であり、作成後は内容を変更できません。一方、bytearrayは可変型で、バイトをその場で変更するメソッドをサポートします。
b = bytes([1, 2, 3]) # immutable ba = bytearray([1, 2, 3]) # mutable ba[0] = 99 # OK b[0] = 99 # TypeError
encode()を使用した場合、文字列が何バイトになるかをどうやって知りますか?
バイト数はエンコーディングに依存します。たとえば、'abc'の場合、utf-8では3バイトですが、'こんにちは'では12バイトです。encode()を呼び出した後でのみ、len()を介して正確なサイズを知ることができます:
s = 'こんにちは' # 6文字 b = s.encode('utf-8') # 12バイト print(len(b)) # 12
開発者が'rb'(バイト)モードでファイルを読み込み、すぐに文字列として処理しようとします:
with open('file.txt', 'rb') as f: for line in f: print(line.strip()) # line: bytes
利点:
欠点:
開発者がdecode()を介してバイトストリームを処理し、エンコーディングのチェックを行います:
with open('file.txt', 'rb') as f: for line in f: print(line.decode('utf-8').strip())
利点:
欠点: