Pythonで文字列とバイト型を相互に変換する方法について解説します。
Contents
文字列とバイト型を相互に変換する
Pythonにおける文字列の扱い
Pythonは文字列情報をUnicodeデータとして保存しています。Pythonを利用する環境により、Pythonのファイル(.py)がUTF-8ではなく、それ以外の文字コードで記述されている場合もあります(WindowsではShift-JISなど)。
このような場合でも、Pythonは正常に文字列を扱えるように文字列のエンコーディング情報を管理しており、文字列をエンコード変換して利用しています。この処理はPythonが内部的に実施するためプログラマが意識することは基本的には必要ありません。
しかし、別アプリケーションと文字列をやり取りするような場合などを考慮した場合に、文字コードを意識して文字列を扱う必要が出てきます。
このような場合によく使用するメソッドがencodeメソッドとその逆のメソッドであるdecodeメソッドです。以降では、encodeおよびdecodeメソッドの使い方を紹介していきます。
文字列をバイトに変換する encode
Pythonで指定した文字コードに文字列を変換する場合には、以下のようにencodeメソッドを使用します。
data = "おはようございます。" # encodeで指定文字コードにエンコードする encode_data = data.encode("shift_jis") print(encode_data) print(type(encode_data))
【実行結果】 b'\x82\xa8\x82\xcd\x82\xe6\x82\xa4\x82\xb2\x82\xb4\x82\xa2\x82\xdc\x82\xb7\x81B' <class 'bytes'>
上記例では、「おはようございます。」という文字列をShift-JISでエンコーディングする場合の簡単な例です。
encodeメソッドを使うと、指定した文字コードにエンコードしたデータをbytes型として返却します。上記の実行結果にあるように「b’…….’」と出力されているのは、bytes型であることを示しています。
文字コードとしては他にも、”euc_jp”や”iso2022_jp”などもあります。また、例えば”shift_jis”であれば、別名として”sjis”や”s_jis”などで指定しても構いません。利用できる標準エンコーディングと別名はこちらで確認ができます。
バイト列は0~255の値の羅列なので、外部のシステムなどとのやり取りも簡単です。受け取った側は何の文字コードでエンコーディングしているかさえ知っていれば、適切に自分の環境で元の文字列に戻すことができます。
encodeされたbytes型のデータをもとに戻すには、次に説明するdecodeメソッドを使用します。
バイトを文字列に変換する decode
encodeメソッドでbytes型にした値を元の文字列(str)に戻す際には、以下のようにdecodeメソッドを使用します。
data = "おはようございます。" # encodeで指定文字コードにエンコードする encode_data = data.encode("shift_jis") print(encode_data) print("================================") # decodeで文字列に戻す decode_data = encode_data.decode("shift_jis") print(decode_data) print(type(decode_data))
【実行結果】 b'\x82\xa8\x82\xcd\x82\xe6\x82\xa4\x82\xb2\x82\xb4\x82\xa2\x82\xdc\x82\xb7\x81B' ================================ おはようございます。 <class 'str'>
上記例では「おはようございます。」という文字列をshift_jisでエンコードして、その後decodeメソッドで元の文字列に戻しています。
decodeでエラーとなる場合
文字列に戻す際に、間違った文字コード(例えば’utf_8′)を指定すると以下のようにエラーになることがあるため注意しましょう。
data = "おはようございます。" # encodeで指定文字コードにエンコードする encode_data = data.encode("shift_jis") print(encode_data) print("================================") # decodeで文字列に戻す decode_data = encode_data.decode("utf_8") print(decode_data) print(type(decode_data))
【実行結果例】 UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 0: invalid start byte
encode/decode失敗時の挙動の指定
正しくエンコードやデコードができない場合の挙動の指定は、encode/decodeともにerrorsという引数で挙動を指定することができます。引数として指定できる値と内容は以下の通りです。
なお、デフォルトではerrorsはstrictになっているため、上記の例で見てきたようにエラーが出力されます。
errorsの設定値 | 内容 |
---|---|
strict | 例外を発生して処理を中止する |
ignore | 変換できない文字は除去して、そのまま処理を実行する |
replace | 変換できない文字を「?」等に置換する |
errors=replaceの場合
上記のdecodeで失敗した例で「errors=replace」を指定した場合を見てみましょう。
data = "おはようございます。" # encodeで指定文字コードにエンコードする encode_data = data.encode("shift_jis") print(encode_data) print("================================") # decodeで文字列に戻す decode_data = encode_data.decode("utf_8", errors="replace") print(decode_data) print(type(decode_data))
【実行結果】 b'\x82\xa8\x82\xcd\x82\xe6\x82\xa4\x82\xb2\x82\xb4\x82\xa2\x82\xdc\x82\xb7\x81B' ================================ ���͂悤�������܂��B <class 'str'>
この例だと一部認識できない部分は「�」となっています。replaceなどは、一般的には一部の認識できない文字をスキップする場合などに使用します。
errors=ignoreの場合
「errors=ignore」を指定した場合では、変換のできない文字は以下のように無視されて除去されます。
data = "おはようございます。" # encodeで指定文字コードにエンコードする encode_data = data.encode("shift_jis") print(encode_data) print("================================") # decodeで文字列に戻す decode_data = encode_data.decode("utf_8", errors="ignore") print(decode_data) print(type(decode_data))
【実行結果】 b'\x82\xa8\x82\xcd\x82\xe6\x82\xa4\x82\xb2\x82\xb4\x82\xa2\x82\xdc\x82\xb7\x81B' ================================ ͂悤܂B <class 'str'>
上記に例を見てきましたが、いずれにしても適切な文字に変換ができていないことは事実です。errors引数で処理の挙動を変更できるわけですが、文字コードについてはよく確認してプログラムをするように意識しましょう。
Python2とPython3での文字列/バイト列の扱いの違い
文字列とバイト列の扱いは、Python2からPython3になった際に大きく変更されています。多くはPython3に置き換わってきている印象ですが、もしPython2を使用している場合は注意が必要です。
Python2ではstr型は内部的にはバイト列として扱われていたので、Python3でいうところのbytesに相当しています。Python3でいうところのstrに相当するのは、Python2ではunicode型のため、接頭辞として「u」を付けて「u’おはようございます。’」のような形で表記します。
もし過去から利用しているPython2をPython3に移植するといったことをする場合には、上記のような違いは意識するようにしましょう。
文字列とバイト型の相互変換については、外部システムとのやり取りや暗号化/復号化の際などにも使用したりしますのでしっかりと覚えておきましょう。
まとめ
Pythonで文字列とバイト型を相互に変換する方法について解説しました。
Pythonで指定した文字コードに文字列を変換するにはencodeメソッド、その逆の変換をするにはdecodeメソッドを使用します。また、errors引数により変換失敗時の挙動を指定する方法も紹介しました。
文字列とバイト型の相互変換は、外部システムとのやり取りや暗号化/復号化の際などに使用しますので、しっかり使い方を覚えてもらえればと思います。
上記で紹介しているソースコードについてはgithubにて公開しています。参考にしていただければと思います。