解码Unicode字符串;这意味着什么,我该如何避免呢?

时间:2012-07-21 13:12:08

标签: python unicode character-encoding python-3.x python-2.x

我正在寻找一种将用户提供的字符串转换为UTF-8的简单方法。它不一定非常聪明;它应该处理所有ASCII字节字符串和所有Unicode字符串(2.x unicode,3.x str)。

由于unicode在3.x中消失且str改变了含义,我认为检查是否存在decode方法并在没有参数的情况下调用它可能是一个好主意让Python根据语言环境找出要做的事情,而不是进行isinstance检查。事实证明这根本不是一个好主意:

>>> u"één"
u'\xe9\xe9n'
>>> u"één".decode()
Traceback (most recent call last):
  File "<ipython-input-36-85c1b388bd1b>", line 1, in <module>
    u"één".decode()
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

我的问题是双重的:

  1. 为什么会有unicode.decode方法呢?我认为Unicode字符串被认为是“未编码”。这看起来是获得双重编码字符串的可靠方法。
  2. 如何以与Python 3向前兼容的方式解决此问题?

3 个答案:

答案 0 :(得分:5)

说“解码”unicode字符串是没用的。您希望 en 将其编码为字节。 unicode.decode完全出于历史原因;它的语义毫无意义。因此,它已在Python 3中删除。

但是encode / decode语义历来被扩展为包括(字符)字符串到字符串或字节到字节的编码,例如rot13或bzip2的。在Python 3.1中,删除了这些伪编码,reintroduced in Python 3.2

通常,您应该设计接口,以便它们接受字符或字节字符串。接受这两者的接口(出于向后兼容性以外的原因)是代码异味,难以测试,容易出现错误(如果有人通过UTF-16字节会怎么样?)并且首先会出现可疑的语义。

如果您必须具有接受字符和字节字符串的接口,则可以检查Python 3中是否存在decode方法。如果您希望代码也在2.x中工作,{ {3}}

答案 1 :(得分:1)

str和unicode之间的转换不是编码/解码的唯一目的。还有编解码器。

例如(在Python 2中):

>>> u'123'.encode('hex')
'313233'
>>> '313233'.decode('hex')
'123'
>>> u'313233'.decode('hex')
'123'

我对Python 3的熟悉程度不足以说明它是否适用于此。

答案 2 :(得分:1)

  1. Unicode对象有一个decode()方法,因为它继承自basestring,而basestring有一个,所以Unicdode也必须有一个。

  2. 您在Python 2或Python 3中永远不会解码Unicode字符串来解决这个问题。正如您所说,这样做是没有意义的。所以不要。

  3. 如何在Python 2和Python 3中的兼容等待中处理这个问题?好吧,你不使用字符串作为二进制数据,你使用bytes。它们有一个适用于所有Python版本的decode()方法。

    有关详情,请参阅http://python3porting.com/noconv.htmlhttp://regebro.wordpress.com/2011/03/23/unconfusing-unicode-what-is-unicode/