在python文件中编写utf-8字符串

2024-05-17 00:49:48 发布

您现在位置:Python中文网/ 问答频道 /正文

py文件中的这一行给出了一个:“unicodedecoderror:”utf8“编解码器无法解码位置8-13中的字节:不支持的Unicode代码范围”

if line.startswith(u"Fußnote"):

文件以utf-8格式保存,其顶部有编码: #--编码:utf-8--

我还有很多其他的py文件,它们的注释和数组中都有utf-8编码的中文文本,例如:arr=[u“chinese text”,]所以我想知道为什么这个例子对我来说不起作用。


Tags: 文件代码py编码if字节编解码器line
3条回答

我可以用以下代码复制unicodedecoderror:

#!/usr/bin/env python
# -- coding: utf-8 --

line='Fußnoteno'
if line.startswith(u"Fußnote"):
    print('Hi')

注意line是一个字符串对象,但是u"Fußnote"是一个unicode对象。 由于line是一个字符串对象,因此在对startswith的调用中将unicode对象转换为字符串对象。在Python2中,默认情况是尝试使用ascii编解码器解码。 由于u"ß"无法用ascii编码解码器解码,因此引发了UnicodeDecodeError。

如果首先使line成为unicode对象,则可以避免此错误:

line='Fußnoteno'.decode('utf-8')
if line.startswith(u"Fußnote"):
    print('Hi')

或者,如果您首先将u"Fußnote"设为字符串对象:

line='Fußnoteno'
if line.startswith(u"Fußnote".encode('utf-8')):
    print('Hi')

让我们仔细检查错误消息:

“UnicodeDecodeError:'utf8'编码解码器无法解码位置8-13中的字节:不支持的Unicode代码范围”

请注意,上面写着“位置8-13的字节”--这是一个6字节的UTF-8序列。这在黑暗时代可能是有效的,但是由于Unicode被冻结在21位,最大值是4字节。UTF-8验证和错误报告were tightened up recently;有趣的是,您运行的究竟是哪一版本的Python?

至少有了2.7.1和2.6.6,这个错误就变得更有用了。。。无法解码位置8中的字节XXXX:无效起始字节“,其中,如果旧消息建议使用6字节序列,则XXXX只能是0xfc或0xfd。在ISO-8859-1或cp1252中,0xfc表示带分音符的U+00FC拉丁文小写字母U(又名U-umlaut,可能是嫌疑人);0xfd表示带锐音符的U+00FD拉丁文小写字母Y(可能不是)。

问题不在于源文件中的if line.startswith(u"Fußnote"):语句。如果不是正确的UTF-8,那么在编译时就会收到一条消息,并且该消息将以“SyntaxError”开头,而不是“UnicodeDecodeError”。无论如何,该字符串的UTF-8编码只有8个字节长,而不是14个字节长。

问题在于(正如@Mark Tolonen所指出的那样)无论“行”指的是什么。它只能是str对象。

为了更进一步,你需要回答马克的问题(1)改变print repr(line)(2)site.py的结果。

在这个阶段,清除混合strunicode对象的空气是个好主意(在许多操作中,不仅仅是a.startswith(b))。

除非定义操作以生成str对象,否则它不会强制unicode对象成为str这不是a.startswith(b)的情况。它将尝试使用默认(通常是“ascii”)编码解码str对象。

示例:

>>> "\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)

此外,说“Mix and you get UnicodeDecodeError”是不正确的。很有可能str对象以默认编码(通常为“ascii”)进行有效编码——不会引发异常。

示例:

>>> "abc".startswith(u"\xff")
False
>>> u"\xff".startswith("abc")
False
>>>

错误表明line不是Unicode字符串。在X.startswith(Y)中,X和Y都必须是Unicode或字节字符串。混在一起,你就成了独角兽。print repr(line)来检查它。您是否还更改了site.py以将默认编码从“ascii”更改为“utf8”?通常,它是Python 2.x的默认“ascii”编解码器

相关问题 更多 >