我得到了一个在Windows上创建的pickle对象(一个包含几个numpy数组的列表),显然已保存到以文本形式加载的文件中,而不是以二进制模式(即使用open(filename, 'w')
代替{ {1}})。结果是,现在我无法解开它(甚至在Windows上),因为它感染了open(filename, 'wb')
个字符(可能还有更多)?主要抱怨是
\r
据说是因为它正在寻找ImportError: No module named multiarray
,这当然不存在。简单地删除numpy.core.multiarray\r
个字符并不起作用(在{python \r
中同时尝试了sed -e 's/\r//g'
,但是两个都打破了文件并稍后产生了s = file.read().replace('\r', '')
)< / p>
问题是我真的需要从对象中获取数据。任何想法如何修复文件?
编辑:根据要求,我的文件的前几百个字节,八进制:
cPickle.UnpicklingError
您也可以下载whole file(22k)。
答案 0 :(得分:13)
假设文件是使用默认的protocol = 0 ASCII兼容方法创建的,您应该可以使用open('pickled_file', 'rU')
(即通用换行符)将其加载到任何位置。
如果这不起作用,请向我们显示前几百个字节:print repr(open('pickled_file', 'rb').read(200))
并将结果粘贴到您的问题的修改中。
更新:
您的文件以'\x80\x02'
开头;它被倾倒了协议2,最新/最好的。协议1和2是二进制协议。您的文件是在Windows上以文本模式编写的。这导致每个'\n'
被C运行时转换为'\r\n'
。文件应该以二进制模式打开,如下所示:
with open('result.pickle', 'wb') as f: # b for binary
pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)
with open('result.pickle', 'rb') as f: # b for binary
obj = pickle.load(f)
文档为here。此代码可在Windows和非Windows系统上轻松运行。
您可以通过以二进制模式读取文件来恢复原始的pickle图像,然后通过'\r\n'
替换所有出现的'\n'
来反转损坏。注意:无论您是否尝试在Windows上读取它,都必须执行此恢复过程。
答案 1 :(得分:5)
Windows中的换行符不仅仅是'\r'
,还有CRLF或'\r\n'
。
尝试file.read().replace('\r\n', '\n')
。您之前删除了可能实际上不属于换行符的回车。
答案 2 :(得分:0)
不能 - 在Windows上 - 只需在文本模式下打开文件,就像编写文件一样,读入文件然后将其写入另一个以二进制模式正确打开的文件中?
答案 3 :(得分:0)
您是否在文字模式下尝试 unpickling ?也就是说,
x = pickle.load(open(filename, 'r'))
(当然是在Windows上。)