u"" 字面量使用的编码是什么

6 投票
1 回答
511 浏览
提问于 2025-04-17 10:18

考虑下面这个例子:

>>> s = u"баба"
>>> s
u'\xe1\xe0\xe1\xe0'
>>> print s
áàáà

我在使用 cp1251 编码,但似乎解释器实际上是用 latin1 来创建 Unicode 字符串:

>>> print s.encode('latin1')
баба

这是为什么呢?有没有相关的规范说明这种行为?

CPython,2.7。


编辑

我其实想找的代码是

>>> u'\xe1\xe0\xe1\xe0' == u'\u00e1\u00e0\u00e1\u00e0'
True

看起来当用 latin1 编码 Unicode 时,所有小于 256 的 Unicode 点都保持不变,这样就得到了我之前输入的字节。

1 个回答

8

当你在终端输入一个字符,比如 б,你看到的是 б,但实际上输入的是一串字节。

因为你的终端编码是 cp1251,所以输入 баба 时,实际上生成的是用 cp1251 编码的 баба 的字节序列:

In [219]: "баба".decode('utf-8').encode('cp1251')
Out[219]: '\xe1\xe0\xe1\xe0'

(注意,我上面用的是 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'

这个 Unicode 恰好代表 áàáà

当你输入:

>>> print s.encode('latin1')

时,latin1 编码会把 u'\xe1\xe0\xe1\xe0' 转换成 '\xe1\xe0\xe1\xe0'。终端接收到的字节序列是 '\xe1\xe0\xe1\xe0',然后用 cp1251 解码,最终打印出 баба

In [222]: print('\xe1\xe0\xe1\xe0'.decode('cp1251'))
баба

试试:

>>> s = "баба"

(去掉 u)来看看效果。或者,

>>> s = "баба".decode('cp1251')

s 变成 unicode。或者,使用比较详细但非常明确的(并且与终端编码无关)方式:

>>> s = u'\N{CYRILLIC SMALL LETTER BE}\N{CYRILLIC SMALL LETTER A}\N{CYRILLIC SMALL LETTER BE}\N{CYRILLIC SMALL LETTER A}'

或者用简短但不太容易理解的方式:

>>> s = u'\u0431\u0430\u0431\u0430'

撰写回答