中国語と日本語(および他の言語)の文字が多数含まれているjsonファイルがあります。次のように_io.open
_を使用して、python 2.7スクリプトにロードしています。
_with io.open('multiIdName.json', encoding="utf-8") as json_data:
cards = json.load(json_data)
_
Jsonに新しいプロパティを追加します。すべて良いです。次に、別のファイルに書き戻そうとします。
_with io.open("testJson.json",'w',encoding="utf-8") as outfile:
json.dump(cards, outfile, ensure_ascii=False)
_
それがエラー_TypeError: must be unicode, not str
_を受け取るときです
私はoutfileをバイナリ(with io.open("testJson.json",'wb') as outfile:
)として書き込もうとしましたが、最終的には次のようになりました:
_{"multiverseid": 262906, "name": "\u00e6\u00b8\u00b8\u00e9\u009a\u00bc\u00e7\u008b\u00ae\u00e9\u00b9\u00ab", "language": "Chinese Simplified"}
_
Ensure_asciiフラグと同様に、同じエンコーディングでそれを開いて書くだけで十分だと思いましたが、明らかにそうではありません。スクリプトを実行する前に、ファイルに存在する文字を\ uに変換せずに保持したいだけです。
以下を試すことができますか?
with io.open("testJson.json",'w',encoding="utf-8") as outfile:
outfile.write(unicode(json.dumps(cards, ensure_ascii=False)))
このエラーの理由は、json.dumps
in Python 2:
>>> json.dumps({'a': 'a'}, ensure_ascii=False)
'{"a": "a"}'
>>> json.dumps({'a': u'a'}, ensure_ascii=False)
u'{"a": "a"}'
>>> json.dumps({'a': 'ä'}, ensure_ascii=False)
'{"a": "\xc3\xa4"}'
>>> json.dumps({u'a': 'ä'}, ensure_ascii=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/json/__init__.py", line 250, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "/usr/lib/python2.7/json/encoder.py", line 210, in encode
return ''.join(chunks)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)
これは、io.open
encoding
が設定されている場合、unicode
オブジェクト(それ自体が正しい)のみを受け入れ、問題が発生します。
戻り型は、辞書内のキーまたは値のタイプに完全に依存します(ensure_ascii=False
、ただしstr
は、ensure_ascii=True
。誤って8ビット文字列を辞書に設定できる場合、needを設定する必要があるため、この戻り値の型を盲目的にunicode
に変換することはできませんエンコーディング、おそらくUTF-8:
>>> x = json.dumps(obj, ensure_ascii=False)
>>> if isinstance(x, str):
... x = unicode(x, 'UTF-8')
thisの場合、json.dump
開いているバイナリファイルに書き込む。ただし、結果のオブジェクトでもっと複雑なことをする必要がある場合は、おそらく上記のコードが必要です。
1つの解決策は、Python 3。
JSONモジュールはエンコードとデコードを処理するため、入力ファイルと出力ファイルをバイナリモードで簡単に開くことができます。 JSONモジュールはUTF-8エンコードを想定していますが、load()
およびdump()
メソッドのencoding
属性を使用して変更できます。
with open('multiIdName.json', 'rb') as json_data:
cards = json.load(json_data)
その後:
with open("testJson.json", 'wb') as outfile: json.dump(cards, outfile, ensure_ascii=False)
@Antti Haapalaのおかげで、Python 2.x JSONモジュールは、オブジェクトのコンテンツに応じてUnicodeまたはstrを提供します。
io
を使用して書き込む前に、結果がUnicodeであることを確認するために、センスチェックを追加する必要があります。
with io.open("testJson.json", 'w', encoding="utf-8") as outfile:
my_json_str = json.dumps(my_obj, ensure_ascii=False)
if isinstance(my_json_str, str):
my_json_str = my_json_str.decode("utf-8")
outfile.write(my_json_str)