json_obj["description"]
は実際にはUTF-8でエンコードされたstr
であり、unicode
ではありません。したがって、write
をcodecs
-wrappedファイルにしようとすると、Pythonはstr
からunicode
にデコードして再エンコードする必要があります。自動デコードではという'ascii'
が使用されるため、これが失敗する部分です。例えば
:
>>> f = codecs.open('emoji.txt', 'w+', encoding='utf-8')
>>> e = u'\U0001f1ef'
>>> print e
>>> e
u'\U0001f1ef'
>>> f.write(e)
>>> e8 = e.encode('utf-8')
>>> e8
'\xf0\x9f\x87\xaf'
>>> f.write(e8)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 0: ordinal not in range(128)
2つの解決策はここにあります。
まず、すべてをできるだけ早くunicode
に明示的にデコードすることができます。あなたのjson_obj
がどこから来ているのか分かりませんが、実際にはstdlib json.loads
ではないと思われます。なぜなら、デフォルトでは常にunicode
のキーと値が与えられるからです。したがって、あなたがJSON用に使用しているものをstdlib関数に置き換えると、おそらく問題が解決されます。
第2に、すべてをUTF-8 str
オブジェクトとして残して、バイナリモードを維持できます。どこでもUTF-8を使用していることがわかっている場合は、codecs.open
の代わりにopen
のファイルのみを使用し、エンコードなしで書き込みます。
また、あなたは強くcodecs.open
の代わりにio.open
を使用することを検討すべきです。
- 誤った値を渡すと間違ったことをするのではなく、例外を発生させます。
- 頻繁に速くなります。
- Python 3と前方互換性があります。
codecs
にバックポートされない数多くのバグ修正があります。
唯一の欠点は、Python 2.5と下位互換性がないことです。あなたにとって重要でない限り、codecs
を使用しないでください。
'json_obj [" description "]'は 'unicode'か' str'ですか?後者の場合は、どのようなエンコーディングですか?また、エラーの直前に 'repr(json_obj [" description "])'を印刷することができます。実際に印刷しようとしているものが見えますか? – abarnert
また、 'json_obj'はどこから来たのですか?名前はstdlibの 'json'モジュールを意味しますが、キーと値が明らかに' str'であるということは、そうでないことを意味します... – abarnert