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

Python

本記事では、Pythonでバイト列(bytes)と文字列(string)を変換する方法を解説します。データ処理やファイル操作、ネットワーク通信などで頻繁に必要となる変換処理について、具体的なコード例とともに説明します。

bytesとstring

まずは、bytesとstringがそれぞれ何かを簡単に説明します。

bytes

bytesはPythonにおけるバイナリデータを表現するためのデータ型です。コンピュータが直接扱うことができる形式で、0から255までの整数値の配列として表現されます。ファイルの読み書き、ネットワーク通信、暗号化処理など、バイナリデータを扱う場面で使用されます。

bytesオブジェクトは不変(イミュータブル)であり、一度作成すると内容を変更することはできません。変更可能なバージョンとしてbytearrayがあります。

bytesリテラルはbで始まる文字列として表現されます。

以下はbytesオブジェクトを作成する例です。

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

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

string

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

stringオブジェクトも不変(イミュータブル)であり、一度作成すると内容を変更することはできません。

以下はstringオブジェクトを作成する例です。

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

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

変換する方法

bytesとstringは異なるデータ型であるため、相互に変換する必要があります。以下では、それぞれの変換方法を説明します。

bytes → string

bytesからstringへの変換は、decodeメソッドを使用します。decodeメソッドは、バイト列をどのエンコーディング(文字コードを定義する規則、例:UTF-8、ASCII、Shift-JISなど)で解釈するかを指定する必要があります。

以下はbytesからstringへの変換例です。

# bytesからstringへの変換
b = b'Hello, World!'
s1 = b.decode('utf-8')  # UTF-8でデコード
s2 = b.decode('ascii')  # ASCIIでデコード

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

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

# 日本語を含むbytesのデコード
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)
print(s_japanese)
# 出力:
# b'\\xe3\\x81\\x93\\xe3\\x82\\x93\\xe3\\x81\\xab\\xe3\\x81\\xa1\\xe3\\x81\\xaf'
# こんにちは

string → bytes

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

以下はstringからbytesへの変換例です。

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

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

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

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

print(s_japanese)
print(b_japanese)
print(b_japanese.hex())  # 16進数表示
# 出力:
# こんにちは
# b'\\xe3\\x81\\x93\\xe3\\x82\\x93\\xe3\\x81\\xab\\xe3\\x81\\xa1\\xe3\\x81\\xaf'
# e38193e38293e381abe381a1e381af

注意点

bytesとstringの変換を行う際には、いくつかの注意点があります。

エンコーディングの選択

文字列をエンコード/デコードする際には、適切なエンコーディングを選択することが重要です。一般的には、UTF-8が最も広く使われており、多言語対応に適しています。

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

print(b_utf8)
print(b_sjis)
print(len(b_utf8))  # バイト数
print(len(b_sjis))  # バイト数
# 出力:
# b'\\xe6\\x97\\xa5\\xe6\\x9c\\xac\\xe8\\xaa\\x9e'
# b'\\x93\\xfa\\x96\\x7b\\x8c\\xea'
# 9
# 6

エラー処理

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

  • ‘strict’:デフォルト値。エラーが発生すると例外を発生させる
  • ‘ignore’:エラーとなる文字を無視する
  • ‘replace’:エラーとなる文字を置換文字(?や�など)に置き換える
  • ‘xmlcharrefreplace’:エラーとなる文字をXMLエンティティに置き換える(encodeのみ)
  • ‘backslashreplace’:エラーとなる文字をバックスラッシュエスケープシーケンスに置き換える

以下はencodeでのエラー処理の例です。

# encodeのエラー処理の例
s = 'こんにちは'

try:
    # ASCIIは日本語を扱えないのでエラーになる
    b = s.encode('ascii')
except UnicodeEncodeError as e:
    print(f"エラー: {e}")

# エラー処理方法を指定
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)
print(b_replace)
print(b_xmlcharrefreplace)
# 出力:
# エラー: 'ascii' codec can't encode character '\\u3053' in position 0: ordinal not in range(128)
# b''
# b'?????'
# b'&#12371;&#12435;&#12395;&#12385;&#12399;'

以下はdecodeでのエラー処理の例です。

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

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

# エラー処理方法を指定
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))
# 出力:
# デコードエラー: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
# ''
# '���'
# '\\\\xff\\\\xfe\\\\xfd'

まとめ

Pythonにおけるbytesとstringの変換方法について解説しました。

  • bytesはバイナリデータを表現するためのデータ型で、b’…’のように表記される
  • stringはテキストデータを表現するためのデータ型で、’…’のように表記される
  • bytesからstringへの変換には、decode()メソッドを使用する
  • stringからbytesへの変換には、encode()メソッドを使用する
  • エンコーディングの選択が重要で、一般的にはUTF-8が推奨される
  • エラー処理方法を指定することで、変換エラーに対処できる

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

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