読者です 読者をやめる 読者になる 読者になる

ユニコード文字列を含むファイルの読み書きにはcodecsを使う

ある複数のidから特定のidの状態をファイルに保存する簡単なスクリプトだったのだが

# coding=utf-8
import requests

def main():
    ids = range(1, 100)

    with open('hoge', 'w') as f:
        for id in ids:
            data = {}
            data['No'] = id
            r = requests.post(PATH, data)

            if r.json['moge'] == "0":
                flg = u'ほげ'
            elif r.json['moge'] == "1":
                flg = u'とげ'
            elif r.json['moge'] == "2":
                flg = u'もげ'

            f.write("hoge:%s %s" %r.json['hoge'], flg)
            f.write('\n')

if __name__ == "__main__":
    main()

実行すると下記のエラー落ちる

UnicodeEncodeError: 'ascii' codec can't encode characters in position 6-8: ordinal not in range(128)

ググってもよくわからなかったけど、どうもasciiとあるように文字コードまわりで、おそらくユニコード文字列あたりの処理で落ちているというのはわかる。
スクリプト自体はその場凌ぎでどうにかしたのだが、やはり気持ち悪いので少し調べたら、ユニコード文字列を扱う場合は codecs を使うようだ。codecs.open で明示的にエンコード指定をしないといけないようだ。

import codecs
...
with codecs.open('hoge', 'w', 'utf-8') as f:
    ...
    ...

参考:: ファイル入出力時にエンコードを指定する - nelnal@python - pythonグループ