【问题标题】:Encoding used for u"" literals用于 u"" 文字的编码
【发布时间】:2012-01-15 19:50:58
【问题描述】:

考虑下一个例子:

>>> 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 点都被简单地留下,因此导致我之前输入的字节。

【问题讨论】:

  • 你问错问题了。问题不是“Unicode 字符串文字使用什么编码”(一个毫无意义的问题;编码是输入/输出的东西,内部表示显然是可以表示 Unicode 的东西,这就是您需要知道的全部内容)。您真正想知道答案的问题是“为什么 IDLE 会弄乱我的文本编码,它是发生在输入还是输出上,我如何让它做我想做的事?”
  • 你是如何定义你的编码的?请参阅python.org/dev/peps/pep-0263 在源文件中定义编码。请也提供您的python版本。根据docs.python.org/howto/unicode.html,使用的默认编码将是 ASCII。 2.4 之前的 Python 版本以欧洲为中心,并假定 Latin-1 作为字符串文字的默认编码
  • @kindall 好吧,afaik,我们确实需要在创建 unicode 对象时进行编码(因为我们不需要字节,而是有意义的字符)。那么为什么解释器不使用我的实际编码来执行字节->字符转换呢?
  • @Gagandeep cp1251 只是我的默认操作系统编码。
  • 除非您提供,否则解释器无法知道编码。

标签: python unicode encoding


【解决方案1】:

当你在终端中输入б之类的字符时,你会看到б,但真正输入的是一个字节序列。

由于您的终端编码是cp1251,因此键入баба 会产生等于cp1251 中编码的unicode баба 的字节序列:

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'

【讨论】:

    猜你喜欢
    • 2018-05-05
    • 2018-04-15
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 2013-04-21
    • 2015-04-13
    • 2017-02-19
    相关资源
    最近更新 更多