唯物是真 @Scaled_Wurm

プログラミング(主にPython2.7)とか機械学習とか

Pythonで日本語関係のイライラ

Pythonを使い始めたときに,一番よく見るのはUnicode系のエラー(UnicodeEncodeErrorとかUnicodeDecodeErrorとか)だと思います.
日本語を扱ってると非常にイライラしてきます.
基本的な対策をメモしておきます.

対策

ソースコード文字コードを指定

ソースコード内で日本語を使う場合,適切な文字コードをファイルの頭で指定しないと以下のようなエラーになります.

File "test.py", line 1
SyntaxError: Non-ASCII character '\x82' in file test.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

指定方法は以下のようになります.

# -*- coding: utf-8 -*-
内部では常にUnicode文字列を使う

Unicode文字列と通常の文字列が混在しているとめんどくさいので,すべてUnicode文字列に統一しましょう.
扱っている文字列がどちらかわからなくなったときには以下のコマンドで調べられます.

uni = u'str'
raw = 'str'

print type(uni)
print type(raw)
外部とのやり取りは適切なエンコーディングを指定

ファイルを入出力をするときは必ずエンコーディングを指定しましょう.

import codecs
codecs.open(filename, 'r', 'shift_jis')

文字列をコンソールやリダイレクトで出力するときにもエンコーディングを指定したほうが良いです.

sys.stdout = codecs.getwriter('utf_8')(sys.stdout)

入出力のたびに以下のように文字コードを指定してもいいですが,忘れたときは悲惨です.

print u''.encode('shift_jis')

またシステムのデフォルトエンコーディングを変更する必要がある場合もあります.
その時には以下のように記述します.
ただし,この方法は別のライブラリの動作など思いがけない場所に影響を及ぼす可能性があります.

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

この設定を継続したい場合には以下のようにsitecustomize.pyファイルに書きこむ必要があります.

import sys
sys.setdefaultencoding('utf-8')
日本語を含むリスト

日本語を含むリストなどがエスケープされて表示されてしまいわかりづらいです.
以下のリンクのような方法を使えばわかりやすい出力が見られます.

コピペしづらいので整形して転載.

import re, pprint
def pp(obj):
  pp = pprint.PrettyPrinter(indent=4, width=160)
  str = pp.pformat(obj)
  return re.sub(r"\\u([0-9a-f]{4})", lambda x: unichr(int("0x"+x.group(1), 16)), str)
csv.reader

csv.readerをunicode文字列に対して直接は使えません.
対策は以下のリンクを参照.

まとめ

  1. ソースコードエンコーディングを指定する.
  2. 内部では常にunicode文字列を使う.
  3. printやファイルなどの入出力をする時には必ずエンコーディングを指定する.

最終手段はPython 3.xを使うことです.
基本的にunicode文字列で扱うことになるので,きっと幸せになれるはずです……