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

Python 解码Unicode字符串;这意味着什么?我如何避免?,python,unicode,character-encoding,python-3.x,python-2.x,Python,Unicode,Character Encoding,Python 3.x,Python 2.x,我正在寻找一种将用户提供的字符串转换为UTF-8的简单方法。它不必非常聪明;它应该处理所有ASCII字节字符串和所有Unicode字符串(2.xUnicode,3.xstr) 由于unicode在3.x中消失了,str改变了含义,因此我认为最好检查decode方法的存在,并调用该方法,而不使用参数,让Python根据区域设置确定要做什么,而不是执行isinstance检查。结果证明这根本不是个好主意: >>> u"één" u'\xe9\xe9n' >>> u

我正在寻找一种将用户提供的字符串转换为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)
>>u“俎n”
u'\xe9\xe9n'
>>>解码
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
解码
UnicodeEncodeError:“ascii”编解码器无法对位置0-1中的字符进行编码:序号不在范围内(128)
我的问题有两个方面:

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

  • 说“解码”unicode字符串是没有用的。你想把它编码成字节
    unicode。decode
    仅因历史原因而存在;它的语义毫无意义。因此,它在Python 3中已被删除

    然而
    编码
    /
    解码
    语义在历史上已经扩展到包括(字符)字符串到字符串或字节到字节的编码,如rot13或bzip2。在Python3.1中,这些伪编码被删除,并且

    通常,您应该设计接口,使其接受字符或字节字符串。接受两者的接口(除了向后兼容性之外)是一种代码味道,很难测试,容易出现错误(如果有人通过UTF-16字节怎么办?),并且首先语义有问题


    如果必须有一个同时接受字符和字节字符串的接口,那么可以检查Python 3中是否存在
    decode
    方法。如果您希望代码也能在2.x中工作,那么“解码”unicode字符串是没有用的。你想把它编码成字节
    unicode。decode
    仅因历史原因而存在;它的语义毫无意义。因此,它在Python 3中已被删除

    然而
    编码
    /
    解码
    语义在历史上已经扩展到包括(字符)字符串到字符串或字节到字节的编码,如rot13或bzip2。在Python3.1中,这些伪编码被删除,并且

    通常,您应该设计接口,使其接受字符或字节字符串。接受两者的接口(除了向后兼容性之外)是一种代码味道,很难测试,容易出现错误(如果有人通过UTF-16字节怎么办?),并且首先语义有问题


    如果必须有一个同时接受字符和字节字符串的接口,那么可以检查Python 3中是否存在
    decode
    方法。如果您希望代码也能在2.x中工作,那么str和unicode之间的转换并不是编码/解码的唯一目的。还有编解码器

    例如(在Python 2中):


    我对Python3还不太熟悉,无法判断它在那里是否有效。

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

    例如(在Python 2中):

    我对Python3还不够熟悉,无法判断它在那里是否有效

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

  • 在Python2或Python3中,通过从不解码Unicode字符串来解决这个问题。正如你所指出的,这样做毫无意义。所以不要

  • 那么,在Python2和Python3中如何在兼容的等待中处理这个问题呢?嗯,二进制数据不使用字符串,而是使用字节。他们有一个decode()方法,可以在所有版本的Python中使用

    有关这方面的更多信息,请参见和

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

  • 在Python2或Python3中,通过从不解码Unicode字符串来解决这个问题。正如你所指出的,这样做毫无意义。所以不要

  • 那么,在Python2和Python3中如何在兼容的等待中处理这个问题呢?嗯,二进制数据不使用字符串,而是使用字节。他们有一个decode()方法,可以在所有版本的Python中使用


    有关这方面的更多信息,请参见《我的想法》。但是,我如何解决从任何
    基串
    到UTF-8的问题,而不使用
    isinstance
    ?更新了答案。这是一个首先不应该出现的问题——你应该知道你通过了什么。如果您想要Python2和Python3的兼容性,恐怕必须使用
    isinstance
    。正如我所想。但是,我如何解决从任何
    基串
    到UTF-8的问题,而不使用
    isinstance
    ?更新了答案。这是一个首先不应该出现的问题——你应该知道你通过了什么。如果你想要Python2和Python3的兼容性,恐怕你必须使用
    isinstance
    。这正是Python3修复的Unicode字符串解码方法的缺点。这正是Python3修复的Unicode字符串解码方法的缺点。哇,完全出乎意料的是+1。“十六进制”对于字符串到字符串的对话,仅在2.x中可用;哇,完全出乎意料的是+1。字符串对字符串对话的“十六进制”是唯一可用的
    >>> u'123'.encode('hex')
    '313233'
    >>> '313233'.decode('hex')
    '123'
    >>> u'313233'.decode('hex')
    '123'