Establishing why an object can't be pickled

前端 未结 4 2065
小蘑菇
小蘑菇 2021-01-11 14:37

I\'m receiving an object, t, from an api of type Object. I am unable to pickle it, getting the error:

  File \"p.py\", line 55, in          


        
4条回答
  •  南笙
    南笙 (楼主)
    2021-01-11 14:40

    I tried Dill but it didn't explain my issue. Instead, I used the following code from https://gist.github.com/andresriancho/15b5e226de68a0c2efd0, which happened to show a bug in my __getattribute__ override:

    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
    

    Edit: Here's a reproduction of my code, using pickle and cPickle:

    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()
    

    Output:

    Traceback (most recent call last):
    File "/Users/myuser/Documents/workspace/AcceptanceTesting/ingest.py", line 35, in 
      cPickle.dump(myd, myf, protocol=-1)
    UnpickleableError: Cannot pickle  objects
    
    Traceback (most recent call last):
    File "/Users/myuser/Documents/workspace/AcceptanceTesting/ingest.py", line 42, in 
      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: {}
    

    You'll see that the reason is because attribute names are being mangled by __getattribute__

提交回复
热议问题