jmi*_*ite 5 python serialization pickle
我接管了一个相当大的项目的代码.我正在尝试保存程序状态,并且有一个大型对象存储了几乎所有其他对象.我试图挑选这个对象,但是我得到了这个错误:
pickle.PicklingError:不能发泡:它没有被发现为builtin .module
从我在谷歌上可以找到的,这是因为某个地方我正在导入python init之外的东西,或者一个类属性引用一个模块.所以,我有两个问题:
任何人都可以确认这就是为什么会出现这个错误的原因吗?我在代码中寻找正确的东西吗?
有没有办法找到哪一行代码/对象成员导致pickle的困难?回溯仅给出发生错误的pickle中的行,而不是被pickle对象的行.
tjo*_*ans 11
2)你可以将pickle.Pickler和monkey-patch子类化,以显示它的酸洗记录.这样可以更容易地追踪问题所在.
import pickle
class MyPickler (pickle.Pickler):
def save(self, obj):
print 'pickling object', obj, 'of type', type(obj)
pickle.Pickler.save(self, obj)
Run Code Online (Sandbox Code Playgroud)
这只适用于pickle.Pickler的Python实现.在Python 3.x中,pickle模块默认使用C实现,Pickler的纯Python版本称为_Pickler.
# Python 3.x
import pickle
class MyPickler (pickle._Pickler):
def save(self, obj):
print ('pickling object {0} of type {1}'.format(obj, type(obj))
pickle._Pickler.save(self, obj)
Run Code Online (Sandbox Code Playgroud)
类似的东西存在于dill. 让我们看一下对象列表,看看我们能做什么:
>>> import dill\n>>> f = open(\'whatever\', \'w\')\n>>> f.close()\n>>> \n>>> l = [iter([1,2,3]), xrange(5), open(\'whatever\', \'r\'), lambda x:x]\n>>> dill.detect.trace(False)\n>>> dill.pickles(l)\nFalse\nRun Code Online (Sandbox Code Playgroud)\n\n好的,dill未能腌制列表。所以有什么问题?
>>> dill.detect.trace(True)\n>>> dill.pickles(l)\nT4: <type \'listiterator\'>\nFalse\nRun Code Online (Sandbox Code Playgroud)\n\n好的,列表中的第一项无法腌制。剩下的呢?
\n\n>>> map(dill.pickles, l)\nT4: <type \'listiterator\'>\nSi: xrange(5)\nF2: <function _eval_repr at 0x106991cf8>\nFi: <open file \'whatever\', mode \'r\' at 0x10699c810>\nF2: <function _create_filehandle at 0x106991848>\nB2: <built-in function open>\nF1: <function <lambda> at 0x1069f6848>\nF2: <function _create_function at 0x1069916e0>\nCo: <code object <lambda> at 0x105a0acb0, file "<stdin>", line 1>\nF2: <function _unmarshal at 0x106991578>\nD1: <dict object at 0x10591d168>\nD2: <dict object at 0x1069b1050>\n[False, True, True, True]\nRun Code Online (Sandbox Code Playgroud)\n\n嗯。其他物体腌制得很好。那么,让我们替换第一个对象。
\n\n>>> dill.detect.trace(False)\n>>> l[0] = xrange(1,4)\n>>> dill.pickles(l)\nTrue\n>>> _l = dill.loads(dill.dumps(l))\nRun Code Online (Sandbox Code Playgroud)\n\n现在我们的对象泡菜。好吧,我们可以利用在 linux/unix/mac\xe2\x80\xa6 上进行酸洗的一些内置对象共享,那么更强的检查怎么样,比如跨子进程的实际酸洗(就像在 Windows 上发生的那样) )?
\n\n>>> dill.check(l) \n[xrange(1, 4), xrange(5), <open file \'whatever\', mode \'r\' at 0x107998810>, <function <lambda> at 0x1079ec410>]\n>>> \nRun Code Online (Sandbox Code Playgroud)\n\n不,该列表仍然有效\xe2\x80\xa6,因此这是一个可以成功发送到另一个进程的对象。
\n\n现在,关于您的错误,每个人似乎都忽略了\xe2\x80\xa6
\n\n该ModuleType对象不可腌制,这会导致您的错误。
>>> import types\n>>> types.ModuleType \n<type \'module\'>\n>>>\n>>> import pickle\n>>> pickle.dumps(types.ModuleType)\nTraceback (most recent call last):\n File "<stdin>", line 1, in <module>\n File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps\n Pickler(file, protocol).dump(obj)\n File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump\n self.save(obj)\n File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save\n f(self, obj) # Call unbound method with explicit self\n File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 748, in save_global\n (obj, module, name))\npickle.PicklingError: Can\'t pickle <type \'module\'>: it\'s not found as __builtin__.module\nRun Code Online (Sandbox Code Playgroud)\n\n但是,如果我们导入dill,它就会神奇地起作用。
>>> import dill\n>>> pickle.dumps(types.ModuleType)\n"cdill.dill\\n_load_type\\np0\\n(S\'ModuleType\'\\np1\\ntp2\\nRp3\\n."\n>>> \nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
2360 次 |
| 最近记录: |