Python 2 および Python 3 でバイトを文字列に変換する方法

  1. Python 2.x でバイトを文字列に変換する
  2. Python 3.x でバイトを文字列に変換する
  3. バイトを文字列に変換するさまざまな方法のパフォーマンス比較と結論

このチュートリアル記事では、Python 2.x および Python 3.x で「バイト」を文字列に変換する方法を紹介します。

Python 2.x でバイトを文字列に変換する

Python 2.7 の bytesstr と同一であるため、bytes として開始される変数は文字列です。

Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> A = b'cd'
>>> A
'cd'
>>> type(A)
<type 'str'>

Python 3.x でバイトを文字列に変換する

bytes は Python 3 で導入された新しいデータ型です。

Python 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> A = b'cd'
>>> A
b'cd'
>>> type(A)
<class 'bytes'>
>>> 

bytes の要素のデータ型は int です。

>>> A = b'cd'
>>> A[0]
99
>>> type(A[0])
<class 'int'>

Python 3.x で「デコード」を使用してバイトを文字列に変換する

bytes.decode メソッドは、指定された encoding メソッドでバイトを文字列に変換できます。 encoding メソッドをデフォルトのutf-8 のままにしておけば大抵の場合は問題ありませんが、utf-8 ではなく他のエンコード方式でバイトをエンコードできるため、常に安全とは限りません。

>>> b'\x50\x51'.decode()
'PQ'
>>> b'\x50\x51'.decode('utf-8')
'PQ'
>>> b'\x50\x51'.decode(encoding = 'utf-8')
'PQ'

上記のように「バイト」をデコードする 3つの方法は、エンコード方法としてutf-8が使用されるため同一です。

utf-8 を使用するとエラーが発生する可能性がありますが、バイトはエンコードされません。

>>> b'\x50\x51\xffed'.decode('utf-8')
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    b'\x50\x51\xffed'.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 2: invalid start byte

utf-8は正しい codec ではないという UnicodeDecodeError を取得します。

この「エンコーディング」の問題を解決するための 2つのアプローチがあります。

「エラー」へのパラメータとしての backslashreplaceignore または replace

decode には encoding-errors 以外のパラメーターがあります。 「エラー」が発生したときの動作を定義します。 errors のデフォルト値は strict です。これは、デコード処理でエラーが発生するとエラーを発生させることを意味します。

error には、ignorereplace、または他の登録済みのcodecs.register_error 名、たとえば backslashreplace などのオプションがあります。

ignore は間違ったデコードエラーを無視し、可能な限り出力文字列を作成します。

replace は、対応する文字を、指定された encoding メソッドで定義された文字に置き換えます。backslashreplace は、元の bytes と同じ内容でデコードできなかった文字を置き換えます。

>>> b'\x50\x51\xffed'.decode('utf-8', 'backslashreplace')
'PQ\\xffed'
>>> b'\x50\x51\xffed'.decode('utf-8', 'ignore')
'PQed'
>>> b'\x50\x51\xffed'.decode('utf-8', 'replace')
'PQ�ed'

[bytes-]データのエンコーディングが不明な場合、MS-DOS cp437エンコーディングを使用できます。

>>> b'\x50\x51\xffed'.decode('cp437')
'PQ\xa0ed'

Python 3.x でバイトを文字列に変換する chr

chr(i,/) は序数付きの 1 文字の Unicode 文字列を返します。 bytes の要素を string に変換できますが、完全な bytes には変換できません。

リスト内包表記または「マップ」を使用して、個々の要素に chr を使用しながら、変換された「バイト」の文字列を取得できます。

>>> A =  b'\x50\x51\x52\x53'
>>> "".join([chr(_) for _ in A])
'PQRS'
>>> "".join(map(chr, A))
'PQRS'

バイトを文字列に変換するさまざまな方法のパフォーマンス比較と結論

timeit を使用して、このチュートリアルで紹介したメソッド decodechr のパフォーマンスを比較します。

>>> import timeit
>>> timeit.timeit('b"\x50\x51\x52\x53".decode()', number=1000000)
0.1356779
>>> timeit.timeit('"".join(map(chr, b"\x50\x51\x52\x53"))', number=1000000)
0.8295201999999975
>>> timeit.timeit('"".join([chr(_) for _ in b"\x50\x51\x52\x53"])', number=1000000)
0.9530071000000362

上記のパフォーマンスから、decode() ははるかに高速で、chr() は単一の文字列文字から文字列を再構築する必要があるため、比較的非効率的です。

パフォーマンスが重要なアプリケーションでは decode を使用することをお勧めします。

関連記事 - Python Bytes

  • Python バイトを整数に変換する方法
  • Python 2 および Python 3 で Int をバイトに変換する方法
  • Python で文字列をバイトに変換する方法
  • 関連記事 - Python Encoding-Decoding

  • Python バイトを整数に変換する方法
  • Python 2 および Python 3 で Int をバイトに変換する方法
  • Python で文字列をバイトに変換する方法
  • comments powered by Disqus