【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コード表

 

 図中で日本語フォントを利用する

matplotlibで出力する図の中で日本語フォントを使用したい場合はttfファイルのパスを指定する必要がある。ttfファイルが見当たらない場合は新たにダウンロードしてしまうのが手っ取り早いだろう。

例えば、游ゴシック(Yu Gothic)のフォントファイルはこちらのページ(外部リンク)からダウンロード可能。フォルダを適宜解凍すると、入手したttfファイルは

C:/Users/[ユーザー名]/AppData/Local/Microsoft/Windows/Fonts/

などに置かれるので、これを指定する。

from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties # フォントに関するモジュール
from matplotlib.ticker import ScalarFormatter # 軸フォーマットに関するモジュール
import random
fp = FontProperties(fname='C:/Users/[ユーザー名]/AppData/Local/Microsoft/Windows/Fonts/yugothib.ttf') # 任意のパスを指定する

# 点列の座標生成
xs = [ random.random() for i in range(100) ]
ys = [ random.random() for i in range(100) ]

# プロット
ax = plt.figure(figsize=(6,6), dpi=100).add_subplot(111)
ax.scatter(xs, ys, alpha=0.5)
ax.set_xlabel("x 軸",fontproperties=fp, size=12)
ax.set_ylabel("y 軸",fontproperties=fp, size=12)
ax.set_title("ランダムサンプリング",fontproperties=fp, size=12)
plt.show()
ランダムサンプリング

なお、複数のフォントを図中で使い分けることも可能である。

 

 Atomエディタ上で日本語を出力する

Atom内で日本語を含むスクリプトを実行すると標準出力が文字化けする場合がある。これは初期設定が日本語に対応していないためである。Atomの起動時に読み込まれるスクリプトである C:/Users/[ユーザー名]/.atom/init.coffee の中に

process.env.PYTHONIOENCODING = "utf-8";

と書いてAtomを再起動するとコンソールに日本語が問題無く表示されるようになる。追記しても上手くいかない場合はダブルクォーテーションが環境依存文字になっていないかどうかを確認すること。


PythonのTopに戻る