Rom*_*huk 6 python unicode encoding
考虑下一个例子:
>>> s = u"????"
>>> s
u'\xe1\xe0\xe1\xe0'
>>> print s
áàáà
Run Code Online (Sandbox Code Playgroud)
我cp1251在空闲时使用编码,但似乎解释器实际上用于latin1创建unicode字符串:
>>> print s.encode('latin1')
????
Run Code Online (Sandbox Code Playgroud)
为什么这样?这种行为有规格吗?
CPython,2.7.
编辑
我实际上寻找的代码是
>>> u'\xe1\xe0\xe1\xe0' == u'\u00e1\u00e0\u00e1\u00e0'
True
Run Code Online (Sandbox Code Playgroud)
似乎在使用latin1编解码器对unicode进行编码时,所有unicode点都少于256,因此只会产生我之前输入的字节.
当您?在终端中键入一个字符时,您会看到一个?,但实际输入的是一个字节序列.
由于您的终端编码是cp1251,键入????结果的字节序列等于在以下????编码的unicode cp1251:
In [219]: "????".decode('utf-8').encode('cp1251')
Out[219]: '\xe1\xe0\xe1\xe0'
Run Code Online (Sandbox Code Playgroud)
(注意我utf-8上面使用的是因为我的终端编码utf-8不是cp1251.对我来说,"????".decode('utf-8')只是unicode ????.)
由于键入的????结果是字节序列\xe1\xe0\xe1\xe0,因此当您键入u"????"终端时,Python会收到u'\xe1\xe0\xe1\xe0'.这就是你看到的原因
>>> s
u'\xe1\xe0\xe1\xe0'
Run Code Online (Sandbox Code Playgroud)
这个unicode碰巧代表了áàáà.
当你打字
>>> print s.encode('latin1')
Run Code Online (Sandbox Code Playgroud)
该latin1编码转换u'\xe1\xe0\xe1\xe0'到'\xe1\xe0\xe1\xe0'.终端接收字节序列'\xe1\xe0\xe1\xe0',并用它们解码cp1251,从而打印????:
In [222]: print('\xe1\xe0\xe1\xe0'.decode('cp1251'))
????
Run Code Online (Sandbox Code Playgroud)
尝试:
>>> s = "????"
Run Code Online (Sandbox Code Playgroud)
(没有u)代替.要么,
>>> s = "????".decode('cp1251')
Run Code Online (Sandbox Code Playgroud)
制作s unicode.或者,使用详细但非常明确(和终端编码不可知):
>>> s = u'\N{CYRILLIC SMALL LETTER BE}\N{CYRILLIC SMALL LETTER A}\N{CYRILLIC SMALL LETTER BE}\N{CYRILLIC SMALL LETTER A}'
Run Code Online (Sandbox Code Playgroud)
或者简短但不太容易理解
>>> s = u'\u0431\u0430\u0431\u0430'
Run Code Online (Sandbox Code Playgroud)