Estoy tratando de pepinillo un objeto de un (nuevo estilo) de clase I definido. Pero me da el siguiente error:

>>> with open('temp/connection.pickle','w') as f:
...   pickle.dump(c,f)
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/lib/python2.5/pickle.py", line 1362, in dump
    Pickler(file, protocol).dump(obj)
  File "/usr/lib/python2.5/pickle.py", line 224, in dump
    self.save(obj)
  File "/usr/lib/python2.5/pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "/usr/lib/python2.5/pickle.py", line 419, in save_reduce
    save(state)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/usr/lib/python2.5/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/usr/lib/python2.5/pickle.py", line 306, in save
    rv = reduce(self.proto)
  File "/usr/lib/python2.5/copy_reg.py", line 76, in _reduce_ex
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled

Yo no define explícitamente __slots__ en mi clase. Hizo algo que hago de forma implícita la definen? ¿Cómo puedo evitar esto? Qué necesito para definir __getstate__?

Actualización: gnibbler elegido un buen ejemplo. La clase del objeto que estoy tratando de pepinillo envuelve un socket. (Se me ocurre ahora que) sockets definir __slots__ y no __getstate__ por una buena razón. Asumo una vez que el proceso termina, otro proceso no puede unpickle y utilizar el proceso anterior de la conexión de socket. Así que mientras estoy aceptando Alex Martelli‘s una excelente respuesta, voy a tener que seguir una estrategia diferente de decapado para «compartir» el objeto de referencia.

  • Puedes mostrar el código de la clase? Probablemente no hace falta para ver todos los métodos.

3 Comentarios

  1. 29

    La clase que define __ranuras__ (y no __getstate__) puede ser un antepasado de la clase de los suyos, o una clase (o de la clase padre) de un atributo o elemento de la suya, directa o indirectamente: esencialmente, la clase de cualquier objeto en el grafo dirigido de referencias con su objeto como root, desde el decapado necesita para salvar a todo el gráfico.

    Una simple solución a su dilema es utilizar el protocolo -1, que significa «el mejor protocolo de salmuera se puede usar»; el valor predeterminado es un antiguo basado en ASCII protocolo que impone esta limitación sobre __slots__ vs __getstate__. Considerar:

    >>> class sic(object):
    ...   __slots__ = 'a', 'b'
    ... 
    >>> import pickle
    >>> pickle.dumps(sic(), -1)
    '\x80\x02c__main__\nsic\nq\x00)\x81q\x01.'
    >>> pickle.dumps(sic())
    Traceback (most recent call last):
      [snip snip]
        raise TypeError("a class that defines __slots__ without "
    TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
    >>> 

    Como se puede ver, el protocolo de -1 toma la __slots__ en la zancada, mientras que el protocolo predeterminado da la misma excepción que se vio.

    Los problemas con el protocolo -1: se produce una cadena binaria/archivo, en lugar de un ASCII uno como el protocolo predeterminado; el resultado de vinagre de archivo no sería cargable por suficientemente antiguas versiones de Python. Ventajas, además de la clave de una wrt __slots__, incluir más compacto de los resultados, y un mejor rendimiento.

    Si usted está obligado a usar el protocolo predeterminado, entonces usted necesitará identificar exactamente qué clase está dando problemas y exactamente por qué. Podemos discutir las estrategias de si este es el caso (pero si usted posiblemente puede utilizar el -1 protocolo, que es mucho mejor que no vale la pena discutir;-) y la simple inspección de código en busca de la problemática de la clase/objeto está demostrando ser demasiado complicado (que tengo en mente algunos deepcopy basado en trucos para conseguir una útil representación de todo el gráfico, en el caso de que usted se está preguntando).

  2. 6

    Tal vez un atributo de la instancia es el uso de __slots__

    Por ejemplo, socket ha __slots__ lo que no puede ser en escabeche

    Que usted necesita para identificar el atributo que está causando el error y escribir su propia
    __getstate__ y __setstate__ ignorar que el atributo

  3. 2

    De PEP 307:

    La __getstate__ método debe devolver un valor picklable
    representa el estado del objeto sin referencia al objeto
    sí. Si no __getstate__ existe un método, un defecto
    la aplicación se utiliza que devuelve self.__dict__.

Dejar respuesta

Please enter your comment!
Please enter your name here