2013-07-08 12 views
5

私は、ユーザー入力(iPhoneから発信)をテキストファイルに保存できる簡単なスクリプトを作成しようとしています。私が抱えている問題は、ユーザーが絵文字のアイコンを使用すると、すべてが壊れてしまうことです。Python write(iPhone)Emoji to file

OS:Ubuntuの

Pythonのバージョン:2.7.3

私のコードは、現在絵文字を説明変数に渡されると、私はエラーを取得し、この

f = codecs.open(path, "w+", encoding="utf8") 
f.write("Desc: " + json_obj["description"]) 
f.close() 

のように見えます

UnicodeEncodeError: 'ascii'コーデックは、位置7-8の文字をエンコードできません:序数は範囲外です(128)

可能な限りお手伝いさせていただきます。

+0

'json_obj [" description "]'は 'unicode'か' str'ですか?後者の場合は、どのようなエンコーディングですか?また、エラーの直前に 'repr(json_obj [" description "])'を印刷することができます。実際に印刷しようとしているものが見えますか? – abarnert

+0

また、 'json_obj'はどこから来たのですか?名前はstdlibの 'json'モジュールを意味しますが、キーと値が明らかに' str'であるということは、そうでないことを意味します... – abarnert

答えて

3

json_obj["description"]は実際にはUTF-8でエンコードされたstrであり、unicodeではありません。したがって、writecodecs-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を使用しないでください。