这是令人惊讶的,非常令人沮丧,请帮助。
>>> a1 = '\xe5' # type <str>
>>> a2 = u'\xe5' # type <unicode>
>>> ord(a1)
229
>>> ord(a2)
229
>>> print a2.encode('utf-8')
å
>>> print a1.encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)
如果a1和a2具有相同的值,为什么不能编码?
我必须使用一个外部API来返回a1
表单上的unicode数据,这使得它无用。 Python显然坚持<str>
类型的字符串必须只包含ASCII字符,否则它拒绝对它们进行编码。它完全打破了我的申请。
答案 0 :(得分:3)
您只能编码Unicode字符串。如果你在bytes字符串上调用encode,Python会首先使用默认编码解码它 - 因此错误。 (请注意,这种令人困惑的行为仅发生在Python 2中,已在Python 3中删除。)
答案 1 :(得分:0)
在python2
中,字符串是ASCII,而python3
字符串是Unicode。
ASCII字符的值可能只有0到127之间。 但是,Unicode字符可能具有更高的值。
python2
:
>>> a = '\x7f'
>>> a.encode('utf-8')
'\x7f'
>>> a = '\x80'
>>> a.encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: ordinal not in range(128)
python3
:
>>> a = '\x7f'
>>> a.encode('utf-8')
b'\x7f'
>>> a = '\x80'
>>> a.encode('utf-8')
b'\xc2\x80'
这在python2
中使用u
前缀的原因是因为您明确声明&#34; 这是一个Unicode字符串&#34;。
可能值得一读,以便更深入地了解在python2
中使用Unicode:
要使用(损坏的)API,最好将返回的字符串转换为bytearray,但是注意,这在python3
中不起作用。
>>> a = '\xe5'
>>> b = bytearray(a)
>>> b[0]
229
请记住,\xe5
不是有效的Unicode(UTF-8)字符...要将值0xE5
存储在UTF-8编码的字符串中,您需要存储两个字节:0xC3 0xA5
。
答案 2 :(得分:0)
让我把你的困惑撕成碎片。让我们先从str
和unicode
之间的区别开始。在Python 2.X中:
str
是一个8位字符(1字节)的字符串,尽可能打印为ASCII。 str
实际上是一个字节序列,相当于Python 3.X中的bytes
。 * str
没有编码。unicode
是一串Unicode代码点。 其次,编码意味着根据Python documentation:
“将Unicode字符串转换为字节序列的规则称为编码。”
然后,问自己这个问题:编码已经是字节序列的str
是否有意义?答案是不。因为str
已经是一个字节序列。然而编码unicode
确实有意义,为什么?因为它是一串Unicode字符代码点(即U + 00E4')。
答案 3 :(得分:0)
Ignacio建议从其实际编码中解码字节字符串(不是ascii,但是是什么?)让我尝试使用latin-1,即使我认为它应该是utf-8。那很有效!
我从Python2.7 curses模块获取数据。我最好的猜测是问题就在那里。终端的编码是utf-8,但现在可以正常工作。