Pythonでバイト列(bytes)と文字列(string)を変換する方法を解説

Python

Pythonでバイト列(bytes)と文字列(string)を相互に変換するには、encodeメソッドとdecodeメソッドを使用します。本記事では、これらの変換方法と注意点を実用的なコード例とともに解説します。

バイト列と文字列の基本

バイト列(bytes)とは

バイト列はコンピュータが直接扱うバイナリデータを表現するデータ型です。0から255までの整数値の配列として表現され、ファイル操作やネットワーク通信などで使用されます。

バイト列オブジェクトの作成方法を示します。

# バイト列オブジェクトの作成方法
b1 = b'Hello'  # 文字列リテラルの前にbをつける
b2 = bytes([72, 101, 108, 108, 111])  # ASCII値のリストから作成
b3 = bytes.fromhex('48 65 6c 6c 6f')  # 16進数文字列から作成

print(b1)  # b'Hello'
print(b2)  # b'Hello'
print(b3)  # b'Hello'
print(type(b1))  # <class 'bytes'>

文字列(string)とは

文字列は人間が読み書きできるテキストデータを表現するデータ型です。Pythonの文字列はUnicodeをサポートしており、世界中のさまざまな言語の文字を扱えます。

文字列オブジェクトの作成方法を示します。

# 文字列オブジェクトの作成方法
s1 = 'Hello'  # シングルクォート
s2 = "Hello"  # ダブルクォート
s3 = """Hello
World"""  # 三重引用符(複数行)

print(s1)  # Hello
print(s2)  # Hello
print(s3)  # Hello
           # World
print(type(s1))  # <class 'str'>

バイト列と文字列の変換方法

バイト列から文字列への変換(decode)

バイト列から文字列への変換には、decodeメソッドを使用します。変換時にはエンコーディング(文字コード)を指定する必要があります。

英語のテキストをデコードする例を示します。

# バイト列から文字列への変換
b = b'Hello, World!'
s1 = b.decode('utf-8')  # UTF-8でデコード
s2 = b.decode('ascii')  # ASCIIでデコード

print(b)  # b'Hello, World!'
print(s1)  # Hello, World!
print(type(s1))  # <class 'str'>

日本語などの非ASCII文字を含むバイト列をデコードする例を示します。

# 日本語を含むバイト列のデコード
b_japanese = b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'  # 「こんにちは」のUTF-8バイト列
s_japanese = b_japanese.decode('utf-8')

print(b_japanese)  # b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'
print(s_japanese)  # こんにちは

文字列からバイト列への変換(encode)

文字列からバイト列への変換には、encodeメソッドを使用します。変換時にはエンコーディングを指定する必要があります。

英語のテキストをエンコードする例を示します。

# 文字列からバイト列への変換
s = 'Hello, World!'
b1 = s.encode('utf-8')  # UTF-8でエンコード
b2 = s.encode('ascii')  # ASCIIでエンコード

print(s)  # Hello, World!
print(b1)  # b'Hello, World!'
print(type(b1))  # <class 'bytes'>

日本語などの非ASCII文字を含む文字列をエンコードする例を示します。

# 日本語を含む文字列のエンコード
s_japanese = 'こんにちは'
b_japanese = s_japanese.encode('utf-8')  # UTF-8でエンコード

print(s_japanese)  # こんにちは
print(b_japanese)  # b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'
print(b_japanese.hex())  # e38193e38293e381abe381a1e381af

変換時の注意点

エンコーディングの選択

文字列の変換では適切なエンコーディングの選択が重要です。一般的にはUTF-8が多言語対応に適しています。

異なるエンコーディングでの変換例を示します。

# 異なるエンコーディングの比較
s = '日本語'
b_utf8 = s.encode('utf-8')
b_sjis = s.encode('shift_jis')  # 日本語向けエンコーディング

print(b_utf8)  # b'\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e'
print(b_sjis)  # b'\x93\xfa\x96\x7b\x8c\xea'
print(len(b_utf8))  # 9
print(len(b_sjis))  # 6

エラー処理

変換時にエラーが発生した場合の処理方法を指定できます。errorsパラメータを使用して、エラー発生時の挙動を制御します。主な設定値は以下の通りです:

  • strict:デフォルト値。エラーが発生すると例外(UnicodeEncodeError/UnicodeDecodeError)を発生させます
  • ignore:エラーとなる文字を無視します。変換結果からその文字が削除されます
  • replace:エラーとなる文字を置換文字に置き換えます
    • エンコード時は「?」に置換
    • デコード時は「�」(U+FFFD、REPLACEMENT CHARACTER)に置換
  • backslashreplace:エラーとなる文字をバックスラッシュエスケープシーケンス(例:\xff)に置き換えます

適切なエラー処理方法を選択することで、変換エラーが発生しても処理を継続できます。

エンコード時のエラー処理例を示します。

# エンコード時のエラー処理
s = 'こんにちは'

try:
    # ASCIIは日本語を扱えないのでエラーになる
    b = s.encode('ascii')
except UnicodeEncodeError as e:
    print(f"エラー: {e}")  # エラー: 'ascii' codec can't encode character '\u3053' in position 0: ordinal not in range(128)

# エラー処理方法を指定
b_ignore = s.encode('ascii', errors='ignore')  # エラーを無視
b_replace = s.encode('ascii', errors='replace')  # ?に置換
b_xmlcharrefreplace = s.encode('ascii', errors='xmlcharrefreplace')  # XMLエンティティに置換

print(b_ignore)  # b''
print(b_replace)  # b'?????'
print(b_xmlcharrefreplace)  # b'&#12371;&#12435;&#12395;&#12385;&#12399;'

デコード時のエラー処理例を示します。

# デコード時のエラー処理
# 無効なUTF-8バイト列
invalid_bytes = b'\xff\xfe\xfd'

try:
    # 無効なバイト列をUTF-8としてデコードするとエラーになる
    s = invalid_bytes.decode('utf-8')
except UnicodeDecodeError as e:
    print(f"デコードエラー: {e}")  # デコードエラー: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

# エラー処理方法を指定
s_ignore = invalid_bytes.decode('utf-8', errors='ignore')  # エラーを無視
s_replace = invalid_bytes.decode('utf-8', errors='replace')  # �に置換
s_backslash = invalid_bytes.decode('utf-8', errors='backslashreplace')  # バックスラッシュエスケープに置換

print(repr(s_ignore))  # ''
print(repr(s_replace))  # '���'
print(repr(s_backslash))  # '\\xff\\xfe\\xfd'

実用的な使用例

ファイル操作での変換

テキストファイルの読み書き時にエンコード・デコードが使われる例を示します。

# テキストファイルの読み書き
# ファイルへの書き込み
text = "こんにちは、世界!"
with open("sample.txt", "w", encoding="utf-8") as f:
    f.write(text)

# ファイルからの読み込み
with open("sample.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)  # こんにちは、世界!

# バイナリモードでの読み込み
with open("sample.txt", "rb") as f:
    binary_data = f.read()
    print(binary_data)  # b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf\xe3\x80\x81\xe4\xb8\x96\xe7\x95\x8c\xef\xbc\x81'
    # バイナリデータを文字列に戻す
    text_from_binary = binary_data.decode("utf-8")
    print(text_from_binary)  # こんにちは、世界!

ネットワーク通信での変換

HTTPリクエストでのデータ送受信時にエンコード・デコードが使われる例を示します。

import urllib.request
import json

# JSONデータの送信例
data = {"name": "山田太郎", "age": 30}
json_data = json.dumps(data)  # 辞書をJSON文字列に変換
encoded_data = json_data.encode("utf-8")  # バイト列に変換

# リクエストの作成(実際には送信しない例)
req = urllib.request.Request(
    "https://example.com/api",
    data=encoded_data,
    headers={"Content-Type": "application/json"}
)

print(f"送信データ(文字列): {json_data}")  # 送信データ(文字列): {"name": "山田太郎", "age": 30}
print(f"送信データ(バイト列): {encoded_data}")  # 送信データ(バイト列): b'{"name": "\xe5\xb1\xb1\xe7\x94\xb0\xe5\xa4\xaa\xe9\x83\x8e", "age": 30}'

# レスポンスの受信と処理(模擬例)
response_bytes = b'{"status": "success", "message": "\xe5\x87\xba\xe5\x8a\x9b\xe6\x88\x90\xe5\x8a\x9f"}'
response_str = response_bytes.decode("utf-8")  # バイト列を文字列に変換
response_data = json.loads(response_str)  # JSON文字列を辞書に変換

print(f"受信データ(バイト列): {response_bytes}")  # 受信データ(バイト列): b'{"status": "success", "message": "\xe5\x87\xba\xe5\x8a\x9b\xe6\x88\x90\xe5\x8a\x9f"}'
print(f"受信データ(文字列): {response_str}")  # 受信データ(文字列): {"status": "success", "message": "出力成功"}
print(f"ステータス: {response_data['status']}")  # ステータス: success
print(f"メッセージ: {response_data['message']}")  # メッセージ: 出力成功

まとめ

Pythonでのバイト列と文字列の変換方法について解説しました。

  • バイト列から文字列への変換にはdecode()メソッドを使用する
  • 文字列からバイト列への変換にはencode()メソッドを使用する
  • 変換時には適切なエンコーディングを指定する(一般的にはUTF-8が推奨)
  • エラー処理方法を指定することで、変換エラーに対処できる

これらの知識は、ファイル操作、ネットワーク通信、データ処理など、さまざまな場面で役立ちます。適切なエンコーディングを選択し、エラー処理を行うことで、安全なプログラムを作成することができます。

タイトルとURLをコピーしました