Voici l'erreur que j'ai eue aujourd'hui sur http://filmaster.com "> filmaster.com:
PicklingError: Can't pickle: ce n'est pas le même objet que decimal.Decimal
Qu'est-ce que cela veut dire exactement? Cela ne semble pas avoir beaucoup de sens ... Il semble être lié à la mise en cache Django. Vous pouvez voir l'intégralité de la trace ici:
Traceback (dernier appel le plus récent):
Fichier "/home/filmaster/Django-trunk/Django/core/handlers/base.py", ligne 92, dans get_response response = callback (request, * callback_args, ** callback_kwargs)
Fichier "/home/filmaster/film20/film20/core/film_views.py", ligne 193, dans show_film
workflow.set_data_for_authenticated_user ()Fichier "/home/filmaster/film20/film20/core/film_views.py", ligne 518, dans set_data_for_authenticated_user
object_id = self.the_film.parent.id)Fichier "/home/filmaster/film20/film20/core/film_helper.py", ligne 179, dans get_others_ratings
set_cache (CACHE_OTHERS_RATINGS, str (object_id) + "_" + str (user_id), userratings)Fichier "/home/filmaster/film20/film20/utils/cache_helper.py", ligne 80, dans set_cache return cache.set (CACHE_MIDDLEWARE_KEY_PREFIX + full_path, result, get_time (cache_string))
Fichier "/home/filmaster/Django-trunk/Django/core/cache/backends/memcached.py", ligne 37, en jeu
self._cache.set (smart_str (clé), valeur, timeout ou self.default_timeout)Fichier "/usr/lib/python2.5/site-packages/cmemcache.py", ligne 128, dans l'ensemble val, flags = self._convert (val)
Fichier "/usr/lib/python2.5/site-packages/cmemcache.py", ligne 112, dans _convert val = pickle.dumps (val, 2)
PicklingError: Can't pickle: ce n'est pas le même objet que decimal.Decimal
Et le code source de Filmaster peut être téléchargé ici: bitbucket.org/filmaster/filmaster-test
Toute aide sera fortement appréciée.
J'ai eu cette erreur lors de l'exécution dans un ordinateur portable jupyter. Je pense que le problème était que j'utilisais %load_ext autoreload
autoreload 2
. Le redémarrage de mon noyau et sa relance ont résolu le problème.
Une singularité de Pickle est que la façon dont vous importez une classe avant de décaper une de ses instances peut modifier subtilement l'objet mariné. Pickle nécessite que vous ayez importé l'objet à la fois avant de le décaper et avant de le décaper.
Ainsi, par exemple:
from a.b import c
C = c()
pickler.dump(C)
fera un objet subtilement différent (parfois) pour:
from a import b
C = b.c()
pickler.dump(C)
Essayez de jouer avec vos importations, cela pourrait corriger le problème.
Je vais montrer le problème avec les classes simples 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
Cette erreur est affichée parce que nous essayons de vider A, mais parce que nous avons changé son nom pour faire référence à un autre objet "B", le cornichon est en fait confondu avec quel objet à vider - classe A ou B. Apparemment, les gars du cornichon sont très intelligents et ils ont déjà vérifié ce comportement.
Solution: Vérifiez si l'objet que vous essayez de vider a un nom en conflit avec un autre objet.
J'ai démontré le débogage pour le cas présenté ci-dessus avec ipython et ipdb ci-dessous:
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>
J'espère que cela vous évitera quelques maux de tête! Adios !!
Je ne peux pas expliquer pourquoi cela échoue non plus, mais ma propre solution pour résoudre ce problème était de changer tout mon code de faire
from point import Point
à
import point
celui-ci a changé et cela a fonctionné. J'aimerais savoir pourquoi ... hth
Il peut y avoir des problèmes pour démarrer un processus avec multiprocessing
en appelant __init__
. Voici une démo:
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))
Maintenant, avec le code ci-dessus, si nous exécutons ceci:
if __name__ == '__main__':
t = ProcessInitTest(spawn=True)
t.start_process_fail()
for i in range(1000):
t.do_square(i)
Nous obtenons cette erreur:
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__
Et si nous le changeons pour utiliser fork
au lieu de spawn
:
if __name__ == '__main__':
t = ProcessInitTest(spawn=False)
t.start_process_fail()
for i in range(1000):
t.do_square(i)
Nous obtenons cette erreur:
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'
Mais si nous appelons le start_process
méthode, qui n'appelle pas __init__
dans le mp.Process
cible, comme ceci:
if __name__ == '__main__':
t = ProcessInitTest(spawn=False)
t.start_process()
for i in range(1000):
t.do_square(i)
Cela fonctionne comme prévu (que nous utilisions spawn
ou fork
).
Avez-vous en quelque sorte reload(decimal)
, ou monkeypatch le module décimal pour changer la classe Decimal? Ce sont les deux choses les plus susceptibles de produire un tel problème.
Mon problème était que j'avais une fonction avec le même nom défini deux fois dans un fichier. Je suppose donc qu'il était confus de savoir lequel il essayait de mariner.
La même chose m'est arrivée
Le redémarrage du noyau a fonctionné pour moi
J'ai eu le même problème lors du débogage (Spyder). Tout fonctionnait normalement si vous exécutiez le programme. Mais, si je commence à déboguer, je fais face à la picklingError.
Mais, une fois que j'ai choisi l'option Exécuter dans la console dédiée dans Exécuter la configuration par fichier (raccourci: ctrl + F6) tout a fonctionné normalement comme prévu. Je ne sais pas exactement comment il s'adapte.
Remarque: Dans mon script, j'ai de nombreuses importations comme
from PyQt5.QtWidgets import *
from PyQt5.Qt import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import os, sys, re, math
Ma compréhension de base était, à cause de l'étoile (*), je recevais cette picklingError.