u"" 字面量使用的编码是什么
考虑下面这个例子:
>>> 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'