1

別のシステムのcStringIOを介して、次の方法でUnicodeを記述しました。

u'content-length'.encode('utf-8')

そして、、を使用してこれを読み返すとunicode( stringio_fd.read(),'utf-8')、次のようになります。

u'c \ x00 \ x00 \ x00o \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00e \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00- \ x00 \ x00 \ x00l \ x00 \ x00 \ x00e \ x00 \ x00 \ x00n \ x00 \ x00 \ x00g \ x00 \ x00 \ x00t \ x00 \ x00 \ x00h \ x00 \ x00 \ x00 '

上記をターミナルに印刷すると正しい値が得られますが、もちろん、役立つことは何もできません。

Unicodeを印刷( "c \ x00 \ x00 \ x00o \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00e \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00- \ x00 \ x00 \ x00l \ x00 \ x00 \ x00e \ x00 \ x00 \ x00n \ x00 \ x00 \ x00g \ x00 \ x00 \ x00t \ x00 \ x00 \ x00h \ x00 \ x00 \ x00 ")

コンテンツの長さ

Unicodeを印刷( "c \ x00 \ x00 \ x00o \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00e \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00- \ x00 \ x00 \ x00l \ x00 \ x00 \ x00e \ x00 \ x00 \ x00n \ x00 \ x00 \ x00g \ x00 \ x00 \ x00t \ x00 \ x00 \ x00h \ x00 \ x00 \ x00 ")== u'content-length'

誤り

この文字列を同等の文字列に変換するための最も速くて安価な方法は何u'content-type'ですか?cStringIOから変更できません


更新

philhagの答えは正しいですが、問題は次のようです。

StringIO.StringIO(u'content-type')。getvalue()。encode('utf-8')

「コンテンツタイプ」

StringIO.StringIO(u'content-type')。getvalue()。encode('utf-8')。decode('utf-8')

u「コンテンツタイプ」

cStringIO.StringIO(u'content-type')。getvalue()。encode('utf-8')。decode('utf-8')

u'c \ x00 \ x00 \ x00o \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00e \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00- \ x00 \ x00 \ x00t \ x00 \ x00 \ x00y \ x00 \ x00 \ x00p \ x00 \ x00 \ x00e \ x00 \ x00 \ x00 '

cStringIO.StringIO(u'content-type')。getvalue()。encode('utf-8')。decode('utf-8')。decode('utf-32')

u「コンテンツタイプ」

4

2 に答える 2

6

途中で、値をUTF-32としてエンコードしています。それらをデコードするだけです。

>>> b = u"c\x00\x00\x00o\x00\x00\x00n\x00\x00\x00t\x00\x00\x00e\x00\x00\x00\
... n\x00\x00\x00t\x00\x00\x00-\x00\x00\x00l\x00\x00\x00e\x00\x00\x00\
... n\x00\x00\x00g\x00\x00\x00t\x00\x00\x00h\x00\x00\x00"
>>> b.decode('utf-32')
u'content-length'
于 2012-04-20T20:57:09.370 に答える
4

根本的な原因はcStringIO.StringIO(unicode_object)、ナンセンスを生み出すことです。

docs.python.orgの現在の2.Xドキュメントは言う

StringIOモジュールとは異なり、このモジュールは、プレーンASCII文字列としてエンコードできないUnicode文字列を受け入れることができません。

これは役に立たず、正しくありません。下記参照。chmCPython 2.7.2および2.6.6のwin32インストーラーで提供されるドキュメントのバージョンは、次の文で続きます。

Unicode文字列パラメーターを指定してStringIO()を呼び出すと、文字列をエンコードする代わりに、Unicode文字列のバッファー表現がオブジェクトに入力されます。

これは動作の正しい説明です(以下を参照)。振る舞いは素晴らしいものではありません。その文がウェブドキュメントから削除される正当な理由を想像することはできません。

悪い振る舞い:

Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
>>> import StringIO, cStringIO, sys
>>> StringIO.StringIO(u"fubar").getvalue()
u'fubar' <<=== unicode object
>>> cStringIO.StringIO(u"fubar").getvalue()
'f\x00u\x00b\x00a\x00r\x00' <<=== str object
cStringIO.StringIO(u"\u0405\u0406").getvalue()
'\x05\x04\x06\x04' <<=== "accepts"
>>> sys.maxunicode
65535 # your sender presumably emits 1114111 (wide unicode)
>>> sys.byteorder
'little'

したがって、一般的に行う必要があるのは、送信者のPythonのエンディアンとユニコード幅を知っている/推測し、混乱をでデコードすることだけUTF-(16|32)-(B|L)Eです。

あなたの場合、送信者はむしろビザンチンです。たとえば、あなたが始めたものと驚くべき類似性を持ってu'content-length'.encode('utf-8')いるstrオブジェクトです。または例外'content-length'foo.encode(utf8').decode('utf8')生成します。foo

于 2012-04-20T23:57:26.923 に答える