用于u""文字的编码

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,因此只会产生我之前输入的字节.

unu*_*tbu 8

当您?在终端中键入一个字符时,您会看到一个?,但实际输入的是一个字节序列.

由于您的终端编码是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)