Ron*_*hen 10 python intellij-idea pickle python-3.x
我是Python的新手.我正在调整Python 2.X中的其他人的代码到3.5.代码通过cPickle加载文件.我将所有"cPickle"事件更改为"pickle",因为我理解pickle取代了3.5中的cPickle.我得到了这个执行错误:
NameError: name 'cPickle' is not defined
Run Code Online (Sandbox Code Playgroud)
相关代码:
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)
Run Code Online (Sandbox Code Playgroud)
pickle.load
当load_data()
另一个函数调用时,该行发生错误.但是,a)既没有cPickle
也cpickle
没有出现在项目中任何地方的任何源文件中(全局搜索)和b)如果我load_data()
在Python shell中单独运行行,则不会发生错误(但是,我确实得到另一个数据格式错误).正在pickle
打电话cPickle
,如果是这样,我怎么阻止它?
Shell:Python 3.5.0 | Anaconda 2.4.0(x86_64)| (默认,2015年10月20日,14:39:26)[GCC 4.2.1(Apple Inc. build 5577)]在达尔文
IDE:IntelliJ 15.0.1,Python 3.5.0,anaconda
不清楚如何进行.任何帮助赞赏.谢谢.
实际上,如果你有腌制的物品python2.x
,那么一般都可以通过阅读python3.x
.此外,如果你有腌制对象python3.x
,它们通常可以被读取python2.x
,但只有当它们被转储protocol
为2
或更少时.
Python 2.7.10 (default, Sep 2 2015, 17:36:25)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> x = [1,2,3,4,5]
>>> import math
>>> y = math.sin
>>>
>>> import pickle
>>> f = open('foo.pik', 'w')
>>> pickle.dump(x, f)
>>> pickle.dump(y, f)
>>> f.close()
>>>
dude@hilbert>$ python3.5
Python 3.5.0 (default, Sep 15 2015, 23:57:10)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> with open('foo.pik', 'rb') as f:
... x = pickle.load(f)
... y = pickle.load(f)
...
>>> x
[1, 2, 3, 4, 5]
>>> y
<built-in function sin>
Run Code Online (Sandbox Code Playgroud)
此外,如果您正在寻找cPickle
,现在_pickle
,不是pickle
.
>>> import _pickle
>>> _pickle
<module '_pickle' from '/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/lib-dynload/_pickle.cpython-35m-darwin.so'>
>>>
Run Code Online (Sandbox Code Playgroud)
您还询问了如何停止pickle
使用内置(C++)版本.如果您想使用类对象,可以使用_dump
和_load
/或_Pickler
类来完成此操作.困惑?旧的cPickle
现在_pickle
,但是dump
,load
,dumps
,并且loads
都指向_pickle
...同时_dump
,_load
,_dumps
,和_loads
指向纯Python版本.例如:
>>> import pickle
>>> # _dumps is a python function
>>> pickle._dumps
<function _dumps at 0x109c836a8>
>>> # dumps is a built-in (C++)
>>> pickle.dumps
<built-in function dumps>
>>> # the Pickler points to _pickle (C++)
>>> pickle.Pickler
<class '_pickle.Pickler'>
>>> # the _Pickler points to pickle (pure python)
>>> pickle._Pickler
<class 'pickle._Pickler'>
>>>
Run Code Online (Sandbox Code Playgroud)
因此,如果您不想使用内置版本,那么您可以使用pickle._loads
等.
您尝试加载的腌制数据看起来像是由在 Python 2.7 上运行的程序版本生成的。数据包含对 的引用cPickle
。
问题在于,Pickle 作为一种序列化格式,假设您的标准库(以及较小程度上的代码)不会更改序列化和反序列化之间的布局。在 Python 2 和 3 之间,它确实做了很多次。当这种情况发生时,Pickle 就没有迁移的路径了。
您有权访问生成的程序吗mnist.pkl.gz
?如果是这样,请将其移植到 Python 3 并重新运行它以重新生成该文件的 Python 3 兼容版本。
如果没有,您必须编写一个 Python 2 程序来加载该文件并将其导出为可以从 Python 3 加载的格式(根据数据的形状,JSON 和 CSV 是流行的选择),然后编写一个加载该格式的 Python 3 程序然后将其转储为 Python 3 pickle。然后,您可以从原始程序加载该 Pickle 文件。
当然,您真正应该做的是在能够从 Python 3 加载导出格式时停止,并使用上述格式作为实际的长期存储格式。
除了受信任程序之间的短期序列化之外(加载 Pickle 相当于在 Python 虚拟机中运行任意代码),您应该积极避免将 Pickle 用于任何其他用途,因为您发现自己所处的具体情况。
归档时间: |
|
查看次数: |
12294 次 |
最近记录: |