我对Python还不熟悉。我正在将其他人的代码从Python 2.X修改为3.5。代码通过cPickle加载文件。我将所有“cPickle”事件都改为“pickle”,因为我知道pickle在3.5中取代了cPickle。我得到这个执行错误:
NameError: name 'cPickle' is not defined
相关代码:
import pickle
import gzip
...
def load_data():
f = gzip.open('../data/mnist.pkl.gz', 'rb')
training_data, validation_data, test_data = pickle.load(f, fix_imports=True)
f.close()
return (training_data, validation_data, test_data)
当另一个函数调用load_data()
时,错误出现在pickle.load
行中。但是,a)无论cPickle
还是cpickle
都不再出现在项目的任何源文件中(全局搜索),b)如果我在Python shell中单独运行load_data()
中的行,则不会发生错误(但是,我确实收到另一个数据格式错误)。是pickle
在调用cPickle
,如果是,我如何停止它?
外壳: Python3.5.0 |Python2.4.0(x86_64)|(默认值,2015年10月20日,14:39:26) [通用条款第4.2.1条(苹果公司5577号大楼)]
IDE:IntelliJ 15.0.1、Python 3.5.0、anaconda
不清楚如何进行。感谢任何帮助。谢谢。
实际上,如果已经从
python2.x
中选取对象,那么通常可以通过python3.x
读取。此外,如果从python3.x
中选取了对象,则通常可以通过python2.x
读取它们,但前提是它们被转储时protocol
设置为2
或更低。另外,如果您正在寻找
cPickle
,现在是_pickle
,而不是pickle
。您还问了如何使用内置的(C++)版本来阻止^ {CD9>}。如果您想使用类对象,可以使用
_dump
和_load
,或者使用_Pickler
类。困惑的?旧的cPickle
现在是_pickle
,但是dump
,load
,dumps
,和loads
都指向_pickle
…而_dump
,_load
,_dumps
,和_loads
指向纯python版本。例如:因此,如果不想使用内置版本,那么可以使用
pickle._loads
等。在PythonPython3.5中: 用户可以通过以下方式访问cPickle
给Mike McKerns的学分
看起来您试图加载的pickled数据是由运行在Python 2.7上的程序版本生成的。数据包含对
cPickle
的引用。问题在于,Pickle作为序列化格式,假设您的标准库(以及在较小程度上您的代码)不会在序列化和反序列化之间更改布局。它在Python2和3之间做了很多。当这种情况发生时,Pickle没有迁移的路径。
您有权访问生成
mnist.pkl.gz
的程序吗?如果是,请将其移植到Python 3并重新运行,以重新生成与python3兼容的文件版本。如果不是这样,则必须编写一个Python 2程序来加载该文件并将其导出为可从Python 3加载的格式(取决于数据的形状,JSON和CSV是常用的选择),然后编写一个python3程序来加载该格式,然后将其转储为python3 pickle。然后可以从原始程序加载Pickle文件。
当然,您真正应该做的是停止在您能够从Python3加载导出格式的地方——并将上述格式用作实际的长期存储格式。
使用Pickle在受信任的程序之间进行短期序列化(加载Pickle相当于在Python VM中运行任意代码)之外的任何操作都是应该积极避免的,尤其是因为您所处的具体情况。
相关问题 更多 >
编程相关推荐