python - gte - PicklingError: No puede decaparse<class ''decimal.Decimal''>: no es el mismo objeto que decimal.Decimal
gte django (5)
¿De alguna manera reload(decimal)
, o montaste el módulo decimal para cambiar la clase decimal? Estas son las dos cosas que tienen más probabilidades de producir tal problema.
Este es el error que recibí hoy en http://filmaster.com "> filmaster.com:
PicklingError: No se puede pickle: no es el mismo objeto que decimal.Decimal
¿Qué quiere decir eso exactamente? No parece tener mucho sentido ... Parece estar conectado con el almacenamiento en caché de django. Puedes ver todo el traceback aquí:
Rastreo (llamadas recientes más última):
Archivo "/home/filmaster/django-trunk/django/core/handlers/base.py", línea 92, en respuesta get_response = devolución de llamada (solicitud, * callback_args, ** callback_kwargs)
Archivo "/home/filmaster/film20/film20/core/film_views.py", línea 193, en show_film
workflow.set_data_for_authenticated_user ()Archivo "/home/filmaster/film20/film20/core/film_views.py", línea 518, en set_data_for_authenticated_user
object_id = self.the_film.parent.id)Archivo "/home/filmaster/film20/film20/core/film_helper.py", línea 179, en get_others_ratings
set_cache (CACHE_OTHERS_RATINGS, str (object_id) + "_" + str (user_id), datos de uso)Archivo "/home/filmaster/film20/film20/utils/cache_helper.py", línea 80, en set_cache return cache.set (CACHE_MIDDLEWARE_KEY_PREFIX + ruta completa, resultado, get_time (caché)
Archivo "/home/filmaster/django-trunk/django/core/cache/backends/memcached.py", línea 37, en conjunto
self._cache.set (smart_str (clave), valor, timeout o self.default_timeout)Archivo "/usr/lib/python2.5/site-packages/cmemcache.py", línea 128, en el conjunto val, flags = self._convert (val)
Archivo "/usr/lib/python2.5/site-packages/cmemcache.py", línea 112, en _convert val = pickle.dumps (val, 2)
PicklingError: No se puede pickle: no es el mismo objeto que decimal.Decimal
Y el código fuente de Filmaster se puede descargar desde aquí: bitbucket.org/filmaster/filmaster-test
Cualquier ayuda será apreciada.
Puede haber problemas al iniciar un proceso con multiprocessing
llamando a __init__
. Aquí hay 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 esto:
if __name__ == ''__main__'':
t = ProcessInitTest(spawn=True)
t.start_process_fail()
for i in range(1000):
t.do_square(i)
Recibimos 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 lo cambiamos para usar fork
lugar de spawn
:
if __name__ == ''__main__'':
t = ProcessInitTest(spawn=False)
t.start_process_fail()
for i in range(1000):
t.do_square(i)
Recibimos 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 al método start_process
, que no llama a __init__
en el mp.Process
target, 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 espera (si usamos spawn
o fork
).
Tampoco puedo explicar por qué esto está fallando, pero mi propia solución para solucionar este problema fue cambiar todo mi código.
from point import Point
a
import point
Éste cambio y funcionó. Me encantaría saber por qué ... hth
Una rareza de Pickle es que la forma en que importa una clase antes de que decante una de sus instancias puede cambiar sutilmente el objeto decapado. Pickle requiere que haya importado el objeto de forma idéntica antes de que lo haga y antes de que lo saque.
Así por ejemplo:
from a.b import c
C = c()
pickler.dump(C)
hará un objeto sutilmente diferente (a veces) para:
from a import b
C = b.c()
pickler.dump(C)
Intenta jugar con tus importaciones, podría corregir el problema.
Recibí este error cuando se ejecuta en un cuaderno jupyter. Creo que el problema fue que estaba usando %load_ext autoreload
autoreload 2
. Reiniciando mi kernel y ejecutando de nuevo resolví el problema.