确定无法腌制对象的原因

问题描述 投票:6回答:4

我从t类型的api收到一个物体Object。我无法腌制它,得到错误:

  File "p.py", line 55, in <module>
    pickle.dump(t, open('data.pkl', 'wb'))
  File "/usr/lib/python2.6/pickle.py", line 1362, in dump
    Pickler(file, protocol).dump(obj)
  File "/usr/lib/python2.6/pickle.py", line 224, in dump
    self.save(obj)
  File "/usr/lib/python2.6/pickle.py", line 313, in save
    (t.__name__, obj))
pickle.PicklingError: Can't pickle 'Object' object: <Object object at 0xb77b11a0>

当我执行以下操作时:

for i in dir(t): print(type(i))

我只得到字符串对象:

<type 'str'>
<type 'str'>
<type 'str'>
...
<type 'str'>
<type 'str'>
<type 'str'>

如何打印Object对象的内容以了解为什么它不能被腌制?

它也有可能是对象包含指向QT对象的C指针,在这种情况下,我对pickle对象没有意义。但我想再次看到对象的内部结构,以便建立这个。

python pickle
4个回答
3
投票

您可能想要阅读qazxsw poi并随后检查您的API qazxsw poi课程。

关于“对象的内部结构”,通常实例属性存储在python docs属性中(因为类属性不是pickle,你只关心实例属性) - 但请注意,你还必须递归检查每个属性都有Objects。


8
投票

我会使用__dict__,它有工具来调查对象内部导致目标对象无法被选择的工具。请参阅此答案以获取示例:__dict__,此Q&A是实际使用的检测工具的示例:dill

Good example of BadItem in Dill Module

但是,最常见的出发点是使用pandas.algos._return_false causes PicklingError with dill.dump_session on CentOS

>>> import dill
>>> x = iter([1,2,3,4])
>>> d = {'x':x}
>>> # we check for unpicklable items in d (i.e. the iterator x)
>>> dill.detect.baditems(d)
[<listiterator object at 0x10b0e48d0>]
>>> # note that nothing inside of the iterator is unpicklable!
>>> dill.detect.baditems(x)
[]

trace还具有跟踪指针引用和对象引用的功能,因此您可以构建对象如何相互引用的层次结构。见:>>> dill.detect.trace(True) >>> dill.detect.errors(d) D2: <dict object at 0x10b8394b0> T4: <type 'listiterator'> PicklingError("Can't pickle <type 'listiterator'>: it's not found as __builtin__.listiterator",) >>>

或者,还有:cloudpickle.py和debugpickle.py,它们大部分都不再开发了。我是dill的作者,并希望尽快合并https://github.com/uqfoundation/dill/issues/58中缺少的这些代码中的任何功能。


1
投票

我试过Dill,但它没有解释我的问题。相反,我使用了dill中的以下代码,这恰好显示了我的dill覆盖中的错误:

https://gist.github.com/andresriancho/15b5e226de68a0c2efd0

编辑:这是我的代码的再现,使用pickle和cPickle:

__getattribute__

输出:

def debug_pickle(instance):
  """
  :return: Which attribute from this object can't be pickled?
  """
  attribute = None

  for k, v in instance.__dict__.iteritems():
      try:
          cPickle.dumps(v)
      except:
          attribute = k
          break

  return attribute

你会看到原因是因为class myDict(dict): def __getattribute__(self, item): # Try to get attribute from internal dict item = item.replace("_", "$") if item in self: return self[item] # Try super, which may leads to an AttribueError return super(myDict, self).__getattribute__(item) myd = myDict() try: with open('test.pickle', 'wb') as myf: cPickle.dump(myd, myf, protocol=-1) except: print traceback.format_exc() try: with open('test.pickle', 'wb') as myf: pickle.dump(myd, myf, protocol=-1) except: print traceback.format_exc() 正在破坏属性名称


0
投票

这是Traceback (most recent call last): File "/Users/myuser/Documents/workspace/AcceptanceTesting/ingest.py", line 35, in <module> cPickle.dump(myd, myf, protocol=-1) UnpickleableError: Cannot pickle <class '__main__.myDict'> objects Traceback (most recent call last): File "/Users/myuser/Documents/workspace/AcceptanceTesting/ingest.py", line 42, in <module> pickle.dump(myd, myf, protocol=-1) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1370, in dump Pickler(file, protocol).dump(obj) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump self.save(obj) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 313, in save (t.__name__, obj)) PicklingError: Can't pickle 'myDict' object: {} 的扩展,在Python 3中。

它:

  • 是递归的,处理问题可能很多层深的复杂对象。 输出的格式为__getattribute__,以便您查看调用哪些成员来解决问题。使用Alastair's solution它只是打印.x[i].y.z....,因为键或值可能是问题,使得更难(但不是不可能)引用dict中的特定键或值。
  • 占更多类型,特别是[key/val type=...]dictlist,需要单独处理,因为它们没有tuple属性。
  • 返回所有问题,而不仅仅是第一个问题。
dict
© www.soinside.com 2019 - 2024. All rights reserved.