Este es el error que tengo hoy en http://filmaster.com»>filmaster.com:

PicklingError: no se Puede pickle : no es lo mismo
objeto como decimal.Decimal

¿Qué tiene que decir exactamente? No parece estar haciendo mucho sentido…
Parece estar relacionado con django de almacenamiento en caché. Usted puede ver toda la rastreabilidad aquí:

Traceback (la mayoría de llamada reciente pasado):

Archivo
«/home/filmaster/django-trunk/django/core/handlers/base.py»,
la línea 92, en get_response respuesta =
de devolución de llamada(solicitud, *callback_args,
**callback_kwargs)

Archivo
«/home/filmaster/film20/film20/core/film_views.py»,
línea 193, en show_film

flujo de trabajo.set_data_for_authenticated_user()

Archivo
«/home/filmaster/film20/film20/core/film_views.py»,
la línea 518, en
set_data_for_authenticated_user

object_id = auto.the_film.el padre de familia.id)

Archivo
«/home/filmaster/film20/film20/core/film_helper.py»,
la línea 179, en get_others_ratings

set_cache(CACHE_OTHERS_RATINGS,
str(object_id) + «_» + str(user_id),
userratings)

Archivo
«/home/filmaster/film20/film20/utils/cache_helper.py»,
línea 80, en set_cache volver
la memoria caché.set(CACHE_MIDDLEWARE_KEY_PREFIX
+ full_path, resultado, get_time(cache_string))

Archivo
«/home/filmaster/django-trunk/django/core/cache/backends/memcached.py»,
en la línea 37, en conjunto

auto._cache.set(smart_str(clave), valor,
tiempo de espera o de auto.default_timeout)

Archivo
«/usr/lib/python2.5/site-packages/cmemcache.py»,
línea 128, en el conjunto de val, flags =
auto._convert(val)

Archivo
«/usr/lib/python2.5/site-packages/cmemcache.py»,
línea 112, en _convert val =
pickle.vertederos(de val, 2)

PicklingError: no se Puede pickle : no es lo mismo
objeto como decimal.Decimal

Y el código fuente para Filmaster puede ser descargado desde aquí: bitbucket.org/filmaster/filmaster-test

Cualquier ayuda será muy apreciada.

  • He recibido un mensaje de error similar después de escribir un erróneos getstate método de un objeto a cambiar su comportamiento de la salmuera. No está seguro de cuál es el problema, pero de verificación para cualquiera de esos.
  • También he visto esto con la clase decoradores, específicamente el de seis.add_metaclass
InformationsquelleAutor michuk | 2009-09-11

6 Comentarios

  1. 44

    Tengo este error cuando se ejecuta en un jupyter notebook. Creo que el problema era que estaba usando %load_ext autoreload autoreload 2. Reiniciar mi kernel y volver a ejecutar resuelto el problema.

    • Parece que la alteración de un método de clase es la causa del problema. Mi conjetura es que el autoreload no es la actualización de una definición almacenada en algún lugar. Reiniciando se soluciona porque la nueva definición se carga en ambos lugares.
  2. 20

    Una rareza de la Salmuera es que la manera de importar una clase antes de la salmuera de uno de los casos pueden cambiar sutilmente el escabeche objeto. Pickle requiere que usted ha importado el objeto de forma idéntica tanto antes de pepinillo y antes de unpickle ella.

    Así, por ejemplo:

    from a.b import c
    C = c()
    pickler.dump(C)

    hará una sutil objeto diferente (a veces) a:

    from a import b
    C = b.c()
    pickler.dump(C)

    Tratar de tocar el violín con sus importaciones, se podría corregir el problema.

    • así que, ¿cómo esta decapado problema se produce sólo una vez en miles de solicitudes y normalmente funciona bien?
  3. 5

    Voy a demostrar que el problema con el simple las clases de Python en Python2.7:

    In [13]: class A: pass  
    In [14]: class B: pass
    
    In [15]: A
    Out[15]: <class __main__.A at 0x7f4089235738>
    
    In [16]: B
    Out[16]: <class __main__.B at 0x7f408939eb48>
    
    In [17]: A.__name__ = "B"
    
    In [18]: pickle.dumps(A)
    ---------------------------------------------------------------------------
    PicklingError: Can't pickle <class __main__.B at 0x7f4089235738>: it's not the same object as __main__.B

    Se muestra este error, porque estamos tratando de volcar Una, sino porque le hemos cambiado el nombre para hacer referencia a otro objeto «B», pepinillo es realmente confundido con que objeto de volcado de clase a o B. al Parecer, pepinillo chicos son muy inteligentes y ellos ya han puesto un cheque en este comportamiento.

    Solución:
    Compruebe si el objeto que está tratando de volcar en conflicto con nombre de otro objeto.

    Me han demostrado de depuración para el caso presentado anteriormente con ipython y ipdb a continuación:

    PicklingError: Can't pickle <class __main__.B at 0x7f4089235738>: it's not the same object as __main__.B
    
    In [19]: debug
    > /<path to pickle dir>/pickle.py(789)save_global()
        787                 raise PicklingError(
        788                     "Can't pickle %r: it's not the same object as %s.%s" %
    --> 789                     (obj, module, name))
        790
        791         if self.proto >= 2:
    
    ipdb> pp (obj, module, name)               **<------------- you are trying to dump obj which is class A from the pickle.dumps(A) call.**
    (<class __main__.B at 0x7f4089235738>, '__main__', 'B')
    ipdb> getattr(sys.modules[module], name)   **<------------- this is the conflicting definition in the module (__main__ here) with same name ('B' here).**
    <class __main__.B at 0x7f408939eb48>

    Espero que este guarda algunos dolores de cabeza! Adios!!

    • En Python 3 esta decapado de error no existe.
  4. 4

    No puedo explicar por qué esto es no, pero mi propia solución para arreglar esto iba a cambiar todo mi código de hacer

    from point import Point

    a

    import point

    este cambio y funcionó. Me encantaría saber por qué… hth

    • Esto me ayudó así y me encantaría saber por qué!
  5. 3

    Hizo que de alguna manera reload(decimal), o monkeypatch el módulo decimal para cambiar el Decimal de la clase? Estas son las dos cosas más probabilidades de producir un problema.

    • Ninguno, nada de ese tipo. Estoy solo de la importación Decimal de la clase.
  6. 3

    Puede tener problemas a partir de un proceso con multiprocessing llamando __init__. He aquí una demostración:

    import multiprocessing as mp
    
    class SubProcClass:
        def __init__(self, pipe, startloop=False):
            self.pipe = pipe
            if startloop:
                self.do_loop()
    
        def do_loop(self):
            while True:
                req = self.pipe.recv()
                self.pipe.send(req * req)
    
    class ProcessInitTest:
        def __init__(self, spawn=False):
            if spawn:
                mp.set_start_method('spawn')
            (self.msg_pipe_child, self.msg_pipe_parent) = mp.Pipe(duplex=True)
    
        def start_process(self):
            subproc = SubProcClass(self.msg_pipe_child)
            self.trig_proc = mp.Process(target=subproc.do_loop, args=())
            self.trig_proc.daemon = True
            self.trig_proc.start()
    
        def start_process_fail(self):
            self.trig_proc = mp.Process(target=SubProcClass.__init__, args=(self.msg_pipe_child,))
            self.trig_proc.daemon = True
            self.trig_proc.start()
    
        def do_square(self, num):
            # Note: this is an synchronous usage of mp,
            # which doesn't make sense. But this is just for demo
            self.msg_pipe_parent.send(num)
            msg = self.msg_pipe_parent.recv()
            print('{}^2 = {}'.format(num, msg))

    Ahora, con el código anterior, si ejecutamos este:

    if __name__ == '__main__':
        t = ProcessInitTest(spawn=True)
        t.start_process_fail()
        for i in range(1000):
            t.do_square(i)

    Obtenemos este error:

    Traceback (most recent call last):
      File "start_class_process1.py", line 40, in <module>
        t.start_process_fail()
      File "start_class_process1.py", line 29, in start_process_fail
        self.trig_proc.start()
      File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/process.py", line 105, in start
        self._popen = self._Popen(self)
      File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/context.py", line 212, in _Popen
        return _default_context.get_context().Process._Popen(process_obj)
      File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/context.py", line 274, in _Popen
        return Popen(process_obj)
      File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/popen_spawn_posix.py", line 33, in __init__
        super().__init__(process_obj)
      File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/popen_fork.py", line 21, in __init__
        self._launch(process_obj)
      File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/popen_spawn_posix.py", line 48, in _launch
        reduction.dump(process_obj, fp)
      File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/reduction.py", line 59, in dump
        ForkingPickler(file, protocol).dump(obj)
    _pickle.PicklingError: Can't pickle <function SubProcClass.__init__ at 0x10073e510>: it's not the same object as __main__.__init__

    Y si cambiamos a utilizar fork en lugar de spawn:

    if __name__ == '__main__':
        t = ProcessInitTest(spawn=False)
        t.start_process_fail()
        for i in range(1000):
            t.do_square(i)

    Obtenemos este error:

    Process Process-1:
    Traceback (most recent call last):
      File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/process.py", line 254, in _bootstrap
        self.run()
      File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/process.py", line 93, in run
        self._target(*self._args, **self._kwargs)
    TypeError: __init__() missing 1 required positional argument: 'pipe'

    Pero si llamamos a la start_process método, que no llame a __init__ en el mp.Process de destino, de esta manera:

    if __name__ == '__main__':
        t = ProcessInitTest(spawn=False)
        t.start_process()
        for i in range(1000):
            t.do_square(i)

    Funciona como se esperaba (si usamos spawn o fork).

Dejar respuesta

Please enter your comment!
Please enter your name here