標準出力とリダイレクトのエンコーディング
lxmlで取得したデータを、print で出力させて
リダイレクトでファイルに保存しようとしたら
”UnicodeEncodeError"が発生してはまりまくったのでメモ
詳しくは、[Python-ml-jp 3250] で書かれています。
とても分かりやすいので、リンク先の参照をおすすめします。
http://www.python.jp/pipermail/python-ml-jp/2005-March/003247.html
発生していた問題:
1. unicodeオブジェクトをいきなりprint文で印字しようとした。
2. その結果、Pythonの「暗黙のエンコード」が起きた。
3. デフォルトのエンコード名が、"None"と判定された。
4. Python側で、"None"の代わりに"ascii"を使用してエンコードした。
5. ”UnicodeEncodeError"が発生した。
デフォルトのエンコード名は、"sys.stdout.encoding"で取得できます。
標準出力の場合は、正しい値が取得できますが、リダイレクトをさせると
この値が変わってしまうため、問題となりました。
確認用プログラム
# coding: utf-8 # vim: fileencoding=utf-8 if __name__ == '__main__': import sys print sys.stdout.encoding print sys.getfilesystemencoding()
実効結果
[kuma8@~]$ python stdout_encode.py UTF-8 UTF-8 [kuma8@~]$ python stdout_encode.py > a [kuma8@~]$ cat a None UTF-8
unicodeオブジェクトをprint文で印字させる必要があるときは、
明示的にエンコードをさせるか、unicode→string 変換が
起こらないように処置するのが無難なようです。
# unicode→string 変換をさせない print repr(str) # 明示的なエンコード print str.encode(sys.getfilesystemencoding())