ユーニックス総合研究所

  • home
  • archives
  • python-byte-to-string

Pythonでbytes型をstr型に(byte to string)変換する

  • 作成日: 2022-05-09
  • 更新日: 2023-12-25
  • カテゴリ: Python

byte to string

Pythonにはバイト列型と文字列型があります。
これはbytesとstrです。

この記事ではbytesをstrに変換する方法について具体的に解説します。

関連記事

頭が悪い人のPythonのevalの使い方
頭がいい人のPythonのexitの使い方
状態遷移による文字列パースのテクニック【Python】

頭が悪い人のPythonのevalの使い方
頭がいい人のPythonのexitの使い方
状態遷移による文字列パースのテクニック【Python】

bytesをstrに変換する

バイト列のリテラルはプレフィクスにbがつきます。
たとえば↓はバイト列です。

b'abc123'  

このバイト列を文字列に変換するにはdecode()に変換します。
「バイトのオデコに文字列」で覚えておきましょう。

s = b'abc123'.decode('utf-8')  

print(type(s))  
print(s)  
<class 'str'>  
abc123  

decode()の引数にはエンコーディング形式を指定します。
↑の例ではutf-8に変換しています。
結果はUTF-8でエンコーディングされた文字列になります。

strをbytesに変換する

文字列をバイト列に変換するにはencode()を使います。

b = 'abc123'.encode('utf-8')  

print(type(b))  
print(b)  
<class 'bytes'>  
b'abc123'  

encode()の引数にもエンコーディング形式を指定します。
↑の例ではUTF-8に変換しています。

デコードできない文字列

バイト列を文字列にデコードしようとするとたまにデコードできないデータに当たります。
たとえば\x80のようなデータです。
これが含まれるバイト列をデコードしようとするとUnicodeDecodeErrorが送出されます。

try:  
    b'\x80abc'.decode('utf-8')  
except UnicodeDecodeError as e:  
    print(e)  
    # 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte  

↑のようにデコードしようとしてエラーになります。
これはエンコードでも発生します。

こういった変換できないデータに対する振る舞いを指定するにはdecode()の第2引数のerrorsにキーワードを指定します。

errorsによるエラー時のふるまいの指定

decode()encode()の第2引数に指定できるerrorsのキーワードは↓の4種類があります。

  • 'strict' ... UnicodeDecodeError を送出する
  • 'replace' ... REPLACEMENT CHARACTER である U+FFFD を使う
  • 'ignore' ... 結果となる Unicode から単に文字を除く
  • 'backslashreplace' ... エスケープシーケンス \xNN を挿入する

たとえば先ほどの\x80が含まれたデータをreplaceでデコードすると↓のようになります。

s = b'\x80abc'.decode('utf-8', 'replace')  
print(s)  
�abc  

可読性のない文字列(U+FFFD)で置換されてるのがわかります。
ignoreでは↓のようになります。

s = b'\x80abc'.decode('utf-8', 'ignore')  
print(s)  
abc  

↑の場合だと変換できない文字列は無視されているのがわかります。
backslashreplaceでは↓のようになります。

s = b'\x80abc'.decode('utf-8', 'backslashreplace')  
print(s)  
\x80abc  

デコードやエンコードで変換したデータで、変換できない部分があった場合、困ることになるプログラムはあると思います。
それが致命的なエラーになる場合はなおさらです。
そういうときはstrictを使ってUnicodeDecodeErrorを発生させ、ユーザーにエラーを伝えたほうが良いでしょう。

変換できないデータがあってもある程度可能な場合はreplaceignore, backslashreplaceを使えばいいでしょう。
デコードできない状態を保持したい場合はreplace系の指定を使って、結果が文字化けになるようにしたほうがいいかもしれません。
この辺の選択はアプリの設計思想、開発者の判断によります。

encode/decode, どっちだっけ?

バイト列と文字列の相互変換でよくあるのが、どっちのメソッドを使えばいいんだっけ? というケースです。
これは「バイトのオデコに文字列」で、バイト列はdecode()で文字列に変換すると覚えておきましょう。
逆はencode()ですね。

🦝 < バイト君のオデコには文字列が浮かんでいる

🐭 < 第3の目

おわりに

今回はPythonのバイト列を文字列に変換する(byte to string)について解説しました。
バイト列と文字列の相互変換はよく行われます。
ソケット通信や画像処理などではおなじみですね。

🦝 < バイト列を文字列に

🐭 < コンバート