仅在cx_freeze中出现UnicodeDecodeError
我在用cx_freeze把我的脚本打包成可执行文件后,运行程序时遇到了一个错误:"UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 7338: ordinal not in range(128)"
。如果我直接运行这个Python 3脚本,它是可以正常工作的,但一旦我把它打包成可执行文件后再运行,就会出现这个错误。我想发我的代码,但我不太确定该发哪些部分。如果你们知道哪些部分能帮到我,请告诉我,我会发上来。其实我之前也遇到过这个问题并解决了,但时间久了我忘了具体是什么问题,也不记得我是怎么解决的,所以任何帮助或建议都非常感谢!
4 个回答
通过设置默认编码来修复:
reload(sys)
sys.setdefaultencoding("utf-8")
这个错误说明你在Python字符串里有一个不是普通ASCII字符的字符。
>>> b'abc\xa0'.decode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 3: ordinal not in range(128)
我也不知道为什么这个问题只会在脚本被“冻结”时出现。你可以把整个脚本放在一个try
/except
块里,这样可以手动打印出有问题的字符串的全部或部分内容。
编辑:下面是可能的写法
try:
# ... your script here
except UnicodeDecodeError as e:
print("Exception happened in string '...%s...'"%(e.object[e.start-50:e.start+51],))
raise
请告诉我们你使用的Python版本和平台。
展示一下你在出错时看到的完整错误信息。自己看看,最后一行代码是什么?你觉得正在被解码的bytes
字符串是什么?为什么会使用ascii
编码呢?
要注意,Python 3.x并不会自动把bytes
转换成str
,也就是说,它不会用默认的编码(比如ascii)来做这个转换。所以,要么是你自己在做这个转换,要么是cx_freeze在做。
更新:根据评论中的进一步信息。
Excel保存的csv文件并不是用ASCII格式的,而是用微软称之为“ANSI编码页”的格式,这个格式会根据地区不同而有所变化。如果你不知道你的地区是什么,可能是cp1252
。你可以这样检查:
>>> import locale; print(locale.getpreferredencoding())
cp1252
如果Excel真的用ASCII保存文件,你的'\xa0'
字节会被替换成'?',你就不会遇到UnicodeDecodeError错误了。
如果你想把文件保存为UTF-8
格式,你需要用encoding='utf8'
打开文件,这样也会遇到同样的问题(只是你会看到关于0xc2的错误,而不是0xa0)。
你不需要把所有四个csv文件都发到网上。只需运行这个小脚本(未经测试):
import sys
for filename in sys.argv[1:]:
for lino, line in enumerate(open(filename), 1):
if '\xa0' in line:
print(ascii(filename), lino, ascii(line))
这个'\xa0'
是一个不可断行空格
,也就是
……你可能需要编辑你的文件,把这些改成普通空格。
可能你需要在cx_freeze的邮件列表上询问,看看为什么会出现这个错误。他们会想知道完整的错误信息。多练习一下——把它展示在这里。
顺便说一下,“偏移量7338”这个数字挺大的——你期待你的csv文件里有这么长的行吗?也许有什么东西在读取你整个文件……