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'内容长度'

错误的

将此字符串转换为等效于的字符串的最快、最便宜的方法是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 字符串。

这是无用且不正确的;见下文。chm随 CPython 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 的字节顺序和 unicode-width 并用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 回答