我有一个非常特殊的编码问题。我已经看过很多关于这个错误的问题而没有实际答案。我知道Python中的Unicode问题,所以我用:
启动每个文件# -*- coding: utf-8 -*-
然而,当我运行我的软件时,我仍然得到UnicodeDecodeError
。此外,以下代码有效:
# -*- coding: utf-8 -*-
g = " "
s = "2 000€"
if g in s:
print s
错误发生在:
if gap not in tokenString:
tokenString
字符串包含Unicode。有趣的是,如果我尝试在该行之前打印它,它会打印出没有错误。
原因可能是什么?我觉得我错过了什么,我不明白。
EDITED
gap
类型为unicode
,tokenString
类型为str
。
答案 0 :(得分:3)
您没有给我们足够的信息来确定您的问题,但我可以猜测:
如果gap
是str
,而tokenString
是unicode
,则此行:
if gap not in tokenString:
...会尝试将gap
转换为unicode
进行搜索。但是如果gap
有任何非ASCII字符 - 例如,因为它是编码为UTF-8的Unicode字符串 - 这种转换将失败。
例如:
>>> if 'é' in u'a':
... print 'Yes'
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
如果gap
是unicode
并且tokenString
是str
持有非ASCII,则会遇到同样的问题:
>>> if u'a' in 'é':
... print 'Yes'
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
您还会遇到与其他各种混合类型的运算符和方法调用(例如u'a'.find('é')
)相同的问题或类似问题。
解决方案是在in
的两侧使用相同的类型。例如:
>>> if 'é'.decode('utf-8') in u'a':
... print 'Yes'
没有错误。
更大的解决方案是始终在我们的代码中使用一种类型或其他无处不在的。当然在边界,你不能这样做(例如,如果你在任何地方使用unicode
,但是你想要写入一个8位文件),所以你需要显式调用{{1在那些边界处和decode
。但即便如此,你通常可以将其包装起来(例如,使用encode
,或使用自定义文件编写功能,或其他任何内容,因此所有可见代码都是Unicode,填充停止。
或者,当然,您可以使用Python 3,它会立即抓住您尝试比较字节字符串和Unicode字符串并引发codecs.open
,而不是尝试从ASCII解码字节并误导工作或给你一个更混乱的错误...