【Python】日本語を使う

PythonのTopに戻る

 文字コードとencode/decode

英数字は1文字を1バイトのデータ量で表すことができるが、1バイトのデータ量で表現できる文字の数は限られている。東アジアの言語のように、文字によっては2バイト以上のデータ量で表さなければならないのだが、そのような文字を「マルチバイト文字」と呼んでいる。

1バイトで表現できる情報の数は256種類であり、アルファベットと数字だけであれば256通りもあれば十分であるが、アルファベット以外の文字を表現するには圧倒的に不足している。そこで2バイト以上の表現が必要になるのである。マルチバイト文字というのは、例えば日本語圏であれば、ひらがなやカタカナ、漢字が相当する。

※マルチバイト文字に対して、1バイトで表現可能な文字を「シングルバイト文字」と言う。


文字を表すバイト列は文字コードによって異なる。文字列をバイト列に変換するには encode関数 を用いる。例えば「あいうえお」をバイト列に変換すると次のようになる。

string = "あいうえお"

print(string.encode('utf-8'))
# b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a'

print(string.encode('shift-jis'))
# b'\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8'

print(string.encode('EUC-JP'))
# b'\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa'
バイト列の例

ここではUTF-8、Shift-JIS、EUC-JPの3種類の文字コードでバイト列に変換している。

反対にバイト列を文字列に直すには decode関数 を用いる。

string1 = "あいうえお".encode('shift-jis')
print(string1.decode('shift-jis'))
# あいうえお

string2 = "あいうえお".encode('EUC-JP')
print(string2.decode('shift-jis'))
# 、「、、、ヲ、ィ、ェ
バイト列を文字列に直す

前者はShift-JIS方式でエンコードしたバイト列をShift-JIS方式で文字列にデコードしているので正しく「あいうえお」と表示されている。

一方で後者はEUC-JP方式でエンコードしたバイト列をShift-JIS方式で無理やりデコードしているので正しくない表示になってしまっている。これがいわゆる「文字化け」である。

各文字に対応するバイト列は文字コードによって違うので、異なる文字コードで展開された場合は正しく文字列に直せない。このように文字化けは、文字コードAが定めるバイト列を文字コードBのバイト列として翻訳してしまうことによって発生するのである。

※encodeとdecodeがごっちゃになる人は、encodeの方を “en-” =「にする」、”code” =「記号、暗号」の組み合わせで「暗号化する」と覚えておくと良い。decodeは “de-” =「解除する」で「暗号を解く」=「平文に直す」と覚えよう。


プログラムは基本的に英数字と記号類で記述するが、時折コードの中で日本語を利用しなければならない場面が出てくる。文字コードを正しく把握していないと、プログラムがテキストファイルを正しく読み書きできなかったり、スクレイピングなどで取得したテキストが文字化けしたりする可能性があったりする。

Python2系では標準の文字コードが「ASCIIだったため、日本語を扱う際は「# coding: utf-8」などと文字コードを宣言する必要があった。Python3系では標準の文字コードが「UTF-8」となっているので文字コードの宣言は基本的に不要である。Python3系ユーザーの場合、UTF-8を使っていれば基本的に日本語の表示や読み書きで困ることは無いだろう。

※ASCIIとUTF-8の違いは次の通り。
ASCII:1文字を1バイトで表現する最も基本的なエンコーディング方式

UTF-8:ASCIIに世界中の文字を追加するためのエンコーディング方式

※参考にならないかもしれない参考文献:Unicode一覧表UTF-8コード表


PythonのTopに戻る