我在win 7 64位系统中使用python 3.4。我运行了以下代码:
6 """ load single batch of cifar """
7 with open(filename, 'r') as f:
----> 8 datadict = pickle.load(f)
9 X = datadict['data']
错误讯息为UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 0: illegal multibyte sequence
我将第7行更改为:
6 """ load single batch of cifar """
7 with open(filename, 'r',encoding='utf-8') as f:
----> 8 datadict = pickle.load(f)
9 X = datadict['data']
错误信息变为UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte
。
消息最终指向解码中的Python34 \ lib \ codecs.py(自我,输入,最终)。
311 # decode input (taking the buffer into account)
312 data = self.buffer + input
--> 313 (result, consumed) = self._buffer_decode(data, self.errors, final)
314 # keep undecoded input until the next call
315 self.buffer = data[consumed:]
我进一步将代码更改为:
6 """ load single batch of cifar """
7 with open(filename, 'rb') as f:
----> 8 datadict = pickle.load(f)
9 X = datadict['data'] 10 Y = datadict['labels']
好的,这次是UnicodeDecodeError: 'ascii' codec can't decode byte 0x8b in position 6: ordinal not in range(128)
。
问题是什么以及如何解决?
答案 0 :(得分:10)
Pickle文件是二进制数据文件,因此您在加载时始终必须使用'rb'
模式打开文件。不要试图在这里使用文本模式。
您正在尝试加载包含字符串数据的Python 2 pickle。您必须告诉pickle.load()
如何将该数据转换为Python 3字符串,或将它们保留为字节。
默认设置是尝试将这些字符串解码为ASCII,并且解码失败。请参阅pickle.load()
documentation:
可选的关键字参数是 fix_imports , encoding 和 errors ,它们用于控制Python 2生成的pickle流的兼容性支持。 fix_imports 为true,pickle将尝试将旧的Python 2名称映射到Python 3中使用的新名称。 encoding 和 errors 告诉pickle如何解码Python 2腌制的8位字符串实例;这些默认分别为'ASCII'和'strict'。 编码可以是'bytes',将这些8位字符串实例作为字节对象读取。
将编码设置为latin1
可以直接导入数据:
with open(filename, 'rb') as f:
datadict = pickle.load(f, encoding='latin1')
由于集合中的所有字符串仅使用 ,因此numpy
数组数据似乎导致了此处出现问题。
替代方法是使用encoding='bytes'
,但是所有文件名和顶级字典键都是bytes
个对象,您必须解码这些或使用{{1为所有关键文字加前缀}}
答案 1 :(得分:1)
如果要使用utf-8打开文件,则需要编写: 打开(文件名,'r',编码='UTF-8') 如果您要使用GBK打开文件,则需要执行以下操作: 打开(文件名,'rb') 希望能解决您的问题!