Python3.0 で マルチバイト文字を print したらエラーになった
Python3.0 で以下のようなコードを書いて、実行したらエラーになった*1。
#!/usr/bin/env python # -*- coding: utf_8 -*- print('こんにちはこんにちは')
$ python hello.py Traceback (most recent call last): File "test.py", line 8, in <module> print('\u3053\u3093\u306b\u3061\u306f\u3053\u3093\u306b\u3061\u306f') File "/opt/local/Library/Frameworks/Python.framework/Versions/3.0/lib/python3.0/io.py", line 1491, in write b = encoder.encode(s) File "/opt/local/Library/Frameworks/Python.framework/Versions/3.0/lib/python3.0/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-9: ordinal not in range(128)
文字コード周りはあまり良く分らないので、とりあえずググったら、
この場合には、先ほどのsys.getdefaultencoding()で得られる文字コード(エンコーディング)ではなく、環境変数LANG等のロケールで設定された文字コードを使ってエンコードされます。
PythonのUnicodeEncodeErrorを知る - HDEラボ
と出たので、先ほどのファイルに、
#!/usr/bin/env python # -*- coding: utf_8 -*- import sys print(sys.getdefaultencoding()) print(sys.stdout.encoding) print('こんにちはこんにちは')
を加えてみて、実行した。
$ python hello.py utf-8 US-ASCII Traceback (most recent call last): File "test.py", line 8, in <module> print('\u3053\u3093\u306b\u3061\u306f\u3053\u3093\u306b\u3061\u306f') File "/opt/local/Library/Frameworks/Python.framework/Versions/3.0/lib/python3.0/io.py", line 1491, in write b = encoder.encode(s) File "/opt/local/Library/Frameworks/Python.framework/Versions/3.0/lib/python3.0/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-9: ordinal not in range(128)
表示が US-ASCII になってる。
LANGが日本語のときには、想定された動きをします(LANGには端末で出力できる文字コードを設定してください)。
PythonのUnicodeEncodeErrorを知る - HDEラボ
シェルの env を確認したら、export LC_ALL=C となってた。
これを削除して、再度実行すると、
$ python hello.py utf-8 UTF-8 こんにちはこんにちは
ちゃんと意図した通りになった。