Estoy recibiendo un objeto, t, de una api de tipo Object. Soy incapaz de adobar, recibiendo el error:

  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>

Cuando hago lo siguiente:

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

Tengo sólo objetos string:

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

¿Cómo puedo imprimir el contenido de mi Object objeto con el fin de entender por qué no puede ser en escabeche?

También es posible que el objeto contiene C punteros a objetos de QT, en cuyo caso no tendría sentido para mí pickle el objeto. Pero, de nuevo, me gustaría ver la estructura interna del objeto, en el fin de establecer esto.

  • Parece que esto es algo que te de depuración mediante la investigación de la Object tipo, no de la instancia.
  • dir() devuelve una lista de cadena de nombres de variable, no los valores de las variables a sí mismos.
InformationsquelleAutor Baz | 2015-05-28

4 Comentarios

  1. 3

    Usted lo desea, puede leer la python docs y comprobar su API Object clase después.

    Con respecto a la «estructura interna del objeto», generalmente a instancia de los atributos se almacenan en el __dict__ atributo (y dado que los atributos de la clase no son en escabeche sólo la atención acerca de los atributos de instancia) – pero tenga en cuenta que usted va a tener también de forma recursiva inspeccionar el __dict__s para cada atributo.

  2. 8

    Me gustaría utilizar dill, que tiene las herramientas para investigar lo que en el interior de un objeto hace que el objeto de destino a no ser picklable. Ver esta respuesta para un ejemplo: Buen ejemplo de BadItem en el Módulo de Eneldo, y este Q&a para Un ejemplo de la detección de las herramientas en uso real: los pandas.algos._return_false causas PicklingError con el eneldo.dump_session en 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)
    []

    Sin embargo, la más común punto de partida es el uso de 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",)
    >>> 

    dill también tiene la funcionalidad de seguimiento de los punteros de referentes y referentes a objetos, de modo que usted puede construir una jerarquía de cómo los objetos se refieren el uno al otro. Ver: https://github.com/uqfoundation/dill/issues/58

    Alternativamente, también hay: cloudpickle.py y debugpickle.py, que son en su mayor parte ya no desarrollado. Yo soy el dill autor, y espero pronto combinación de la funcionalidad de estos códigos que falta en dill.

  3. 1

    Traté de Eneldo pero no explicar mi problema. En lugar de ello, he utilizado el siguiente código de https://gist.github.com/andresriancho/15b5e226de68a0c2efd0, que pasó a mostrar un error en mi __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: he Aquí una reproducción de mi código, el uso de la salmuera y 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()

    De salida:

    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: {}

    Verás que la razón es porque los nombres de atributos están siendo alterados por __getattribute__

    • Puede usted aclarar lo que significa dill no ayuda, pero el código de arriba lo hizo? El código anterior es una versión más débil de código que existe en dill.detect. Específicamente, dill.detect.badobjects y dill.detect.badtypes. dill también tiene otras herramientas que se muestran en mi respuesta. Si hay algo que dill falta aquí, me gustaría saber.
    • Hola @MikeMcKerns. El eneldo se veía bien, no creo que usted será capaz de código de mi estupidez 🙂 he actualizado mi pregunta con una reproducción de mi código erróneo.
    • Ah… ok, usted tiene un verdadero caso de esquina allí. dill no encontrar el problema en el caso, estoy de acuerdo. Sin embargo, también se nota que debug_pickle en realidad no devolver el mal atributo… esto solo ocurre para no coger el error que hace que la operación de decapado a fallar. Útil, pero aparentemente no intencional. Voy a hacer una nota de este caso como un billete para dill. Gracias.
    • github.com/uqfoundation/dill/issues/154
  4. 0

    Aquí es una extensión de Alastair la solución, en Python 3.

    Es:

    • es recursiva, para tratar con objetos complejos donde el problema puede estar en muchas capas de profundidad.

      La salida es en forma .x[i].y.z.... para permitir que usted vea que los miembros fueron llamados para llegar al problema. Con dict sólo imprime [key/val type=...] lugar, desde cualquiera de las claves o valores puede ser el problema, lo que es más difícil (pero no imposible) para hacer referencia a una clave específica o valor en el dict.

    • cuentas para más tipos, específicamente list, tuple y dict, que necesita ser tratado por separado, ya que no tienen __dict__ atributos.

    • devuelve todos los problemas, en vez de sólo la primera.

Dejar respuesta

Please enter your comment!
Please enter your name here