我正在寻找一种将用户提供的字符串转换为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)
我的问题是双重的:
unicode.decode
方法呢?我认为Unicode字符串被认为是“未编码”。这看起来是获得双重编码字符串的可靠方法。答案 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)
Unicode对象有一个decode()方法,因为它继承自basestring,而basestring有一个,所以Unicdode也必须有一个。
您在Python 2或Python 3中永远不会解码Unicode字符串来解决这个问题。正如您所说,这样做是没有意义的。所以不要。
如何在Python 2和Python 3中的兼容等待中处理这个问题?好吧,你不使用字符串作为二进制数据,你使用bytes
。它们有一个适用于所有Python版本的decode()方法。
有关详情,请参阅http://python3porting.com/noconv.html和http://regebro.wordpress.com/2011/03/23/unconfusing-unicode-what-is-unicode/