我有以下代码
import msgpack
def deserialize(data)
return msgpack.loads(data)
for data in stream:
print deserialize(data)
现在,问题是某些数据(可能)已损坏..我看到了这个错误:
UnicodeDecodeError:'utf8'编解码器无法解码位置0的字节0xcc:无效的连续字节
所以,我试过
def deserialize(data)
try:
return msgpack.loads(data)
except UnicodeDecodeError as e:
logger.error(" error")
但是,代码会以相同的错误停止吗?
答案 0 :(得分:3)
为什么我收到此错误?
有几个可能的原因,但它们都归结为同样的事情:你有一些不是UTF-8的东西,但是你正试图像它一样读它。
首先,如果您实际上有原始二进制数据而不是文本,则无法将其解码为文本。 (在协议版本2.0之前,没有这样的区别,所以如果您从教程或为旧版本编写的示例代码中学习,那将会产生误导。)打包方需要将其显式打包为二进制数据。如果它使用相同的msgpack
库,则使用use_bin_type=True
参数。如果它正在使用其他库,则必须阅读其他库的文档。
其次,如果您有文本,但是打包器将其打包为拉丁语1,则无法将其解压缩为UTF-8。例如,该字节0xcc
表示Latin-1中的Ì
和相关字符集,这是一个完全有效的字符,但它是UTF-8中的错误,除非它遵循前缀字节。 (实际上,你很幸运,你得到了一个错误,而不是默默地做错误的事情并且全都喷出mojibake。)同样,如果打包方使用相同的msgpack
库,那只是传递的问题双方encoding='utf8'
。如果它使用不同的库,您将不得不查看该其他库的文档。 (如果你不能改变另一方,那么你需要弄清楚它正在使用什么编码 - 这可能很难,因为它可能取决于库,平台,甚至用户指定的语言环境或系统默认字符设置...)
我希望捕获此错误,并且无论此错误如何继续用于其余数据。
嗯,那可能不你想做什么......但如果你这样做,你的现有代码应该可以正常工作。它在UnicodeDecodeError
内提升except UnicodeDecodeError as e:
。如果这不起作用,很可能你的实际代码看起来不像你在这里展示的那样。
值得注意的是,您似乎在源代码中混合了制表符和空格,这会导致很多问题 - 看起来它们与人类处于同一缩进级别的东西可能看起来像它们与Python编译器的缩进级别不同,反之亦然。我不太明白这会如何导致您发布的确切代码失败(除非在编译时引发IndentationError
,这听起来不像您所描述的那样),但它很容易导致问题像这样甚至更复杂的代码。
答案 1 :(得分:1)
如果您只想记录' error'
:
def deserialize(data)
try:
return msgpack.loads(data)
except:
logger.error(" error")
如果您想记录错误的性质:
def deserialize(data)
try:
return msgpack.loads(data)
except UnicodeDecodeError as e:
# ... do something with e
如果您想避免错误,这应该解码并替换任何错误的值,see here以获得有关此错误的更优雅的解决方案/信息......
data.decode('utf-8', 'replace').encode('utf-8')
答案 2 :(得分:1)
您可以尝试unicode_errors='ignore' option
msgpack.loads(data, unicode_errors='ignore')