【问题标题】:Decoding a Unicode string; what does that mean and how can I avoid it?解码一个 Unicode 字符串;这是什么意思,我该如何避免呢?
【发布时间】:2012-07-20 12:07:15
【问题描述】:

我正在寻找一种将用户提供的字符串转换为 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 前向兼容的方式解决此问题?

【问题讨论】:

  • 这与 Python 3 修复的 Unicode 字符串上的 decode 方法完全一样。

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


【解决方案1】:

说“解码”一个 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 中工作,you'll have to use isinstance .

【讨论】:

  • 正如我所想。但是,如果没有isinstance,我该如何解决从任何basestring 到UTF-8 的问题?
  • 更新了答案。这是一个首先不应该发生的问题——你应该知道你正在通过什么。如果你想要 Python 2 和 3 的兼容性,恐怕你必须使用 isinstance
【解决方案2】:

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

例如(在 Python 2 中):

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

我对 Python 3 不够熟悉,无法说出这是否适用于那里。

【讨论】:

  • 哇,+1 完全惊喜。
  • "hex" 用于字符串到字符串的转换仅在 2.x 中可用;它has been removed in 3.x.
【解决方案3】:
  1. Unicode 对象有一个 decode() 方法,因为它继承自 basestring 并且 basestring 有一个,所以 Unicdode 也必须有一个。

  2. 在 Python 2 或 Python 3 中,您通过从不解码 Unicode 字符串来解决此问题。正如您所指出的,这样做没有任何意义。所以不要。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-01
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 2013-12-08
    • 1970-01-01
    相关资源
    最近更新 更多