適当のごった煮

Pythonと境界標とQGISを中心にいろいろと

Python3と日本語

スポンサードリンク

Python3になって、すべての文字列がutf-8として扱われることになり、エンコードやデコードの手間がなくなったと思っていたが、理解して使わなければエラーになることは変わりない。

Pythonでの日本語の取り扱いについて自分なりに整理。

ファイルを読み書きするとき、Pythonはシステム(OS)のエンコードから自動でutf-8にエンコードしてくれる。

当初、それを知らずにPython3からutf-8と聞いてテキストファイルをわざわざutf-8で保存して読み込んだら、エラーになってしまった。

>>> f = open('utf-8.txt', 'r')
>>> f
<_io.TextIOWrapper name='utf-8.txt' mode='r' encoding='cp932'> # cp932で読み込まれている
>>> f.read()
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    f.read()
UnicodeDecodeError: 'cp932' codec can't decode byte 0x86 in position 7: illegal multibyte sequence
>>> f.close()

ファイルは、「encoding='cp932'」として認識されている。「cp932」とは大雑把に言うと「Shift_JIS」のマイクロソフト的実装のようだ。

参考:Shitf_JISとCP932とMS932とWindows-31Jを昔話風に語ってみた

従って、OS標準以外の文字コードを使うときは、ファイルを開くときにencodingを指定しなければならない。

>>> f = open('utf-8.txt', 'r', encoding='utf-8')
>>> f
<_io.TextIOWrapper name='utf-8.txt' mode='r' encoding='utf-8'>
>>> f.read()
'UTF-8テスト\n'
>>> f.close()

sys.stdin.encodingで標準入力のエンコーディングが見られる。sys.getfilesystemencoding()では「mbcs」となっており、これは、マルチバイトを使用しないとすべての文字を表現できない国ごと(ロケールごと?)に合わせた文字コードのことのようだ。日本の場合は、「cp932」を意味するらしい。

>>> import sys
>>> sys.stdin.encoding
'cp932'
>>> sys.getfilesystemencoding()
'mbcs'

ひとまず、OSを変えるとか大きな移行をするつもりがない限りは何もしなくて良さそうだけど、遠い将来を考えるとutf-8のほうがいいものか悩みの種。

2016-12-26 追記
openのヘルプを見たらちゃんと「locale.getpreferredencoding(False)」でエンコーディングを取得すると記載がありました。
ちなみに、私の環境(Windows10日本語版)は、'cp932'でした。