3

スペイン語で書かれたデータを含む辞書を含むファイルを作成しました (つまり、 Damiánなど):

fileNameX.write(json.dumps(dictionaryX, indent=4))

データは、いくつかのfqlフェッチ操作から取得されます。つまり、次のとおりです。

select name from user where uid in XXX

ファイルを開くと、たとえば、「Damián」は「Dami\u00e1n」のように見えます。私はいくつかのオプションを試しました:

  1. ensure_ascii=偽:

    fileNameX.write(json.dumps(dictionaryX, indent=4, ensure_ascii=False))
    

    しかし、エラーが発生します( UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position XXX: ordinal not in range(128) )。

  2. エンコード (encoding='latin-1):

    dictionaryX.append({
        'name': unicodeVar.encode(encoding='latin-1'),
         ...
         })
    

    しかし、別のエラーが発生します ( UnicodeDecodeError: 'utf8' codec can't decode byte 0xe1 in position XXX: invalid continuation byte )

要約すると、私はいくつかの可能性を試しましたが、手がかりがありません。道に迷いました。助けてください。ありがとう!

4

3 に答える 3

2

を使用する代わりに、たとえば特定のエンコーディングでcodecs.open()開くために使用します。fileNameX encoding='utf-8'open()

また、json.dump().

于 2012-09-16T21:30:38.320 に答える
2

多くのオプションがあり、Python のバージョンに依存し、正しいコードを書くために絶対に完全に理解する必要があるかなり複雑なものに出くわしました。一般に、3.x で採用されたアプローチはより厳密で、作業が少し難しくなりますが、間違いを犯したり、複雑な状況に陥ったりする可能性ははるかに低くなります。(報告された正確な症状に基づいて、2.x を使用しているようです。)

json.dumps2.x と 3.x では動作が異なります。2.x では、strバイト文字列 (不明なエンコーディング) である が生成されます。3.x でも が生成されstrますがstr、3.x では適切な Unicode 文字列になります。

JSON は本質的に Unicode をサポートする形式ですが、ファイルが UTF-8 エンコーディングであることを想定しています。ただし、JSON は文字列のスタイル エスケープをサポートしている\uことを理解しておいてください。このデータを読み取ると、正しいエンコードされた文字列が返されます。読み取りコードは、JSON から文字列を読み取るときに (2.x または 3.x のどちらを使用しても) Unicode オブジェクトを生成します。

ファイルを開くと、たとえば、「Damián」は「Dami\u00e1n」のように見えます。

áASCII で表すことはできません。\u00e1他の問題を回避するために、デフォルトでエンコードされます。これは 3.x でも発生します。

ensure_ascii=偽

これにより、以前のエンコーディングが無効になります。2.x では、代わりにオブジェクトを取得することを意味します。つまり、元の文字unicodeを保持した実際の Unicode オブジェクトです。á3.x では、文字が明示的に変換されていないことを意味します。しかし、いずれにせよ、それは Unicode string を与えることをensure_ascii=False意味します。json.dumps

Unicode 文字列をファイルに書き込むには、エンコードする必要があります。「Unicode データ」などというものはありません。Unicode は抽象化です。2.x では、'ascii'Unicode オブジェクトを にフィードすると、このエンコーディングは暗黙的に行われますfile.write。を期待していましたstr。これを回避するには、モジュールを使用するか、書く前にcodecs明示的にエンコードします。'utf-8'3.x では、ファイルのエンコードencoding時にキーワード引数を使用してエンコードが設定されopenます (デフォルトはおそらく希望どおりではありません)。

エンコード (encoding='latin-1')

ここでは、辞書を作成する前にエンコードしているため、strデータにオブジェクトが含まれています。strデータにオブジェクトがある場合、JSON エンコーダーはデフォルトで、それらが UTF-8 エンコーディングのUnicode 文字列を表していると想定するため、問題が発生します。これは、2.x ではencodingキーワード引数 toを使用して変更できますjson.dumpsbytes(3.x では、エンコーダーはオブジェクト、つまり非 Unicode 文字列のシリアル化を単純に拒否します!)


ただし、単にデータをファイルに直接取得することが目標である場合、これjson.dumpsは不適切なツールですsその名前が何のためにあるのか疑問に思ったことはありますか?「文字列」の略です。これは特殊なケースです。実際、通常のケースは、ファイルに直接書き込むことです! (文字列を与えて自分で書くことを期待する代わりに。) これがjson.dump(no 's') の機能です。繰り返しになりますが、JSON 標準は UTF-8 エンコーディングを想定しており、2.x にはencodingデフォルトで UTF-8 に設定されるキーワード パラメータがあります (これはそのままにしておく必要があります)。

于 2012-09-16T22:17:52.250 に答える
0

文字列には が含まれているため、\uこれは Unicode 文字列であることを意味します。文字列は実際に正しいです!あなたの問題は、文字列を表示することにあります。文字列の場合print、Python の出力エンコーディングは、環境に適したエンコーディングで出力する必要があります。

たとえば、これは Windows の IDLE 内で得られるものです。

>>> print u'Dami\u00e1n'
Damián
于 2012-09-16T22:24:32.957 に答える