我的.py文件中的这一行给了我一个:"UnicodeDecodeError:'utf8'编解码器无法解码位置8-13中的字节:不支持的Unicode代码范围"
if line.startswith(u"Fußnote"):
Run Code Online (Sandbox Code Playgroud)
该文件保存在utf-8中,编码位于顶部:# - - coding:utf-8 - -
我在注释和数组中有很多其他py文件,其中包含utf-8编码的中文文本,例如:arr = [u"chinese text",]所以我想知道为什么这个案例特别没有'为我工作.
Joh*_*hin 10
让我们仔细研究一下错误信息:
"UnicodeDecodeError:'utf8'编解码器无法解码位置8-13中的字节:不支持的Unicode代码范围"
请注意它说"8-13位的字节" - 这是一个6字节的UTF-8序列.这可能在黑暗时代有效,但由于Unicode被冻结为21位,因此最大值为FOUR字节.最近收紧了 UTF-8验证和错误报告; 感兴趣的是,你正在运行什么版本的Python?
至少2.7.1和2.6.6,该错误变得更有用"......无法解码位置8中的字节XXXX:无效的起始字节",其中XXXX只能是0xfc或0xfd,如果旧消息建议a 6字节序列.在ISO-8859-1或cp1252中,0xfc表示带有DIAERESIS的U + 00FC LATIN SMALL LETTER U(又名u-umlaut,可能是嫌疑人); 0xfd代表U + 00FD LATIN小写字母Y与急性(不太可能).
问题不if line.startswith(u"Fußnote"):在于源文件中的语句.如果它不是正确的UTF-8,你会在COMPILE时收到一条消息,并且消息将以"SyntaxError"开头,而不是"UnicodeDecodeError".在任何情况下,该字符串的UTF-8编码只有8个字节长,而不是14个字节.
问题是(正如@Mark Tolonen指出的那样)无论"线"指的是什么.它只能是一个str对象.
为了更进一步,你需要回答马克的问题(1)print repr(line)(2)site.py改变的结果.
在这个阶段,清除混合str和unicode物体的空气是一个好主意(在许多操作中,不仅仅是a.startswith(b)).
除非定义操作以生成str对象,否则它不会强制unicode对象str.情况并非如此.a.startswith(b)它将尝试str使用默认(通常为"ascii")编码对对象进行解码.
例子:
>>> "\xff".startswith(u"\xab")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)
>>> u"\xff".startswith("\xab")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xab in position 0: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
此外,说"混合你得到UnicodeDecodeError"是不正确的.该str对象很可能以默认编码(通常为"ascii")进行有效编码 - 不会引发异常.
例子:
>>> "abc".startswith(u"\xff")
False
>>> u"\xff".startswith("abc")
False
>>>
Run Code Online (Sandbox Code Playgroud)
我可以使用以下代码重现UnicodeDecodeError:
#!/usr/bin/env python
# -- coding: utf-8 --
line='Fußnoteno'
if line.startswith(u"Fußnote"):
print('Hi')
Run Code Online (Sandbox Code Playgroud)
请注意,它line是一个字符串对象,但是u"Fußnote"是一个unicode对象.由于line是一个字符串对象,因此unicode对象在调用时被转换为字符串对象startswith.在Python2中,默认是尝试使用ascii编解码器进行解码.由于u"ß"无法使用ascii编解码器进行解码,因此会引发UnicodeDecodeError.
如果您首先创建line一个unicode对象,则可以避免该错误:
line='Fußnoteno'.decode('utf-8')
if line.startswith(u"Fußnote"):
print('Hi')
Run Code Online (Sandbox Code Playgroud)
或者如果您首先创建u"Fußnote"一个字符串对象:
line='Fußnoteno'
if line.startswith(u"Fußnote".encode('utf-8')):
print('Hi')
Run Code Online (Sandbox Code Playgroud)