Посмотрите на маринование dict
. Это легко сделать, пока вы не нанесете что-то в него, которое нельзя мариновать.
>>> import pickle
>>> pickle.dumps({})
'(dp0\n.'
>>> pickle.dumps({'a':1})
"(dp0\nS'a'\np1\nI1\ns."
>>> pickle.dumps({'a':1, 'b':(lambda x:x)})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
Pickler(file, protocol).dump(obj)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
self.save(obj)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
save(v)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 748, in save_global
(obj, module, name))
pickle.PicklingError: Can't pickle <function <lambda> at 0x104c765f0>: it's not found as __main__.<lambda>
>>>
Теперь, давайте использовать dill
с рассол след включен, так что мы можем увидеть путь сериализатор берет. dill
может сериализовать lambda
, так что это не подводит.
>>> import dill
>>>
>>> dill.detect.trace(True)
>>> pickle.dumps({})
D2: <dict object at 0x104c3a4b0>
# D2
'(dp0\n.'
>>> pickle.dumps({'a':1})
D2: <dict object at 0x104c3a4b0>
# D2
"(dp0\nS'a'\np1\nI1\ns."
>>> pickle.dumps({'a':1, 'b':(lambda x:x)})
D2: <dict object at 0x104c3a4b0>
F1: <function <lambda> at 0x105c729b0>
F2: <function _create_function at 0x105c0c938>
# F2
Co: <code object <lambda> at 0x104e70830, file "<stdin>", line 1>
F2: <function _unmarshal at 0x105c0c7d0>
# F2
# Co
D3: <dict object at 0x104b95168>
# D3
D2: <dict object at 0x105c30280>
# D2
# F1
# D2
"(dp0\nS'a'\np1\nI1\nsS'b'\np2\ncdill.dill\n_create_function\np3\n(cdill.dill\n_unmarshal\np4\n(S'c\\x01\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x01\\x00\\x00\\x00C\\x00\\x00\\x00s\\x04\\x00\\x00\\x00|\\x00\\x00S(\\x01\\x00\\x00\\x00N(\\x00\\x00\\x00\\x00(\\x01\\x00\\x00\\x00t\\x01\\x00\\x00\\x00x(\\x00\\x00\\x00\\x00(\\x00\\x00\\x00\\x00s\\x07\\x00\\x00\\x00<stdin>t\\x08\\x00\\x00\\x00<lambda>\\x01\\x00\\x00\\x00s\\x00\\x00\\x00\\x00'\np5\ntp6\nRp7\nc__main__\n__dict__\nS'<lambda>'\np8\nNN(dp9\ntp10\nRp11\ns."
Вы можете увидеть пустой dict
, просто dict
(т.е. D2
) маринуется, в то время как с lambda
в dict
, есть несколько объектов, которые получают маринованные ...
- вмещающих
dict
(D2
)
lambda
(F1
)
- несколько вспомогательных функций (
F2
ы)
- код объекта из
lambda
(Co
)
- лямбда-х
__dict__
(D2
)
__main__
__dict__
(т.е. globals()
) (D3
)
Таким образом, травление в dict
легко ... но если что внутри не может быть маринованные, то dict
не может быть маринованный.
(1) вы должны показать свой код, чтобы другие могли легко помочь, и (2) вы можете попробовать 'dill' вместо' cPickle'. Я бы сказал, что использование «укропа» исправит вашу ошибку травления. Большинство объектов ** НЕ МОЖЕТ ** быть маринованными с помощью 'cPickle', однако' dill' может мариновать большинство объектов в python. –
Фактические классы, с которыми я работаю, слишком велики, чтобы вставлять их здесь, и мне все равно не разрешат их показывать. Я не знаю, какой аспект важен. Мне удалось раскрыть один экземпляр с укропом, но не другим (жалуется на '' Can not pickle: это не тот же объект, что и numpy.int64''), когда все экземпляры должны быть одинаковыми для некоторых чисел! => Я надеялся, что кто-то скажет мне, где искать, например. почему словарь будет мариновать, но его компоненты не будут, для начала –
Zak
Да, это известная проблема и не работает, потому что «numpy.int64' не является 'int' ... это экземпляр класса, который частично построен в C ... но что более важно,' numpy.int64' имеет некоторое пространство имен в импорте, которое 'dill' не может отменить и решить. –