10

非ASCII文字を含む着信バイト文字列を有効なutf-8文字列に変換して、jsonとしてダンプできるようにしようとしています。

b = '\x80'
u8 = b.encode('utf-8')
j = json.dumps(u8)

j は '\xc2\x80' であると予想していましたが、代わりに次のようになります。

UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: ordinal not in range(128)

私の状況では、「b」は Google プロトコル バッファ経由で mysql から送信され、いくつかの blob データが入力されています。

何か案は?

編集: mysql テーブルに blob として格納されているイーサネット フレームがあります (皆さん、話題にとどまり、テーブルにパケットがある理由について議論しないでください)。テーブル照合は utf-8 であり、db レイヤー (sqlalchemy、非 orm) はデータを取得し、ブロブを Python 'str' として格納する構造体 (Google プロトコル バッファー) を作成します。場合によっては、問題なくプロトコル バッファを直接使用します。それ以外の場合は、json を介して同じデータを公開する必要があります。私が気付いたのは、json.dumps() が機能するときに、「\x80」を無効な Unicode 文字 (\ufffd iirc) に置き換えることができることです。

4

3 に答える 3

9

使用しているソフトウェア API のドキュメントを調べる必要があります。BLOB は頭字語です: BINARYラージ オブジェクト。

データが実際にバイナリである場合、それを Unicode にデコードするという考えは、もちろんナンセンスです。

実際にテキストである場合は、Unicode にデコードするために使用するエンコーディングを知る必要があります。

次に、...を使用しjson.dumps(a_Python_object)ます...自分でUTF-8にエンコードすると、json再びデコードされます:

>>> import json
>>> json.dumps(u"\u0100\u0404")
'"\\u0100\\u0404"'
>>> json.dumps(u"\u0100\u0404".encode('utf8'))
'"\\u0100\\u0404"'
>>>

についての更新latin1:

u'\x80'は役に立たない無意味な C1 制御文字です。エンコーディングが Latin-1 である可能性は非常に低いです。Latin-1 は「わなと妄想」です。すべての 8 ビット バイトは、例外を発生させずに Unicode にデコードされます。「動作する」と「例外を発生させない」を混同しないでください。

于 2012-03-07T16:07:20.607 に答える
6

b.decode('name of source encoding')Unicode バージョンを取得するために使用します。これは私がそれを知ったとき、私にとって驚きでした。例えば:

In [123]: 'foo'.decode('latin-1')
Out[123]: u'foo'
于 2012-03-07T15:57:29.960 に答える
2

あなたがしようとしているのは、何らかのエンコーディングの文字列オブジェクトをデコードすることだと思います。そのエンコーディングが何であるか知っていますか?Unicode オブジェクトを取得します。

unicode_b = b.decode('some_encoding')

次に、utf_8エンコーディングを使用してUnicodeオブジェクトを文字列オブジェクトに再エンコードします。

b = unicode_b.encode('utf_8')

文字列の元のエンコーディングが何であるかを知らずに、Unicode オブジェクトをトランスレータとして使用すると、確かなことはわかりませんが、変換が期待どおりに行われない可能性があります。Unicode オブジェクトは、あるエンコーディングの文字列を別のエンコーディングに変換するためのものではありません。エンコーディングが何であるかを知っていると仮定して、ユニコードオブジェクトで作業します。エンコーディングが何であるかがわからない場合は、試行錯誤なしで見つける方法が実際にはなく、エンコードされた文字列に戻すときに変換します文字列オブジェクトを戻したい。

于 2012-03-07T16:10:15.430 に答える