Ответ 1
Я получил эту ошибку при работе в ноутбуке jupyter. Я думаю, проблема заключалась в том, что я использовал %load_ext autoreload
autoreload 2
. Перезапуск моего ядра и повторное использование решили проблему.
Это ошибка, которую я получил сегодня на http://filmaster.com" > filmaster.com:
PicklingError: Невозможно рассолчать: это не то же самое объект как decimal.Decimal
Что это значит? Кажется, это не имеет большого смысла... Кажется, это связано с кэшированием django. Здесь вы можете увидеть весь трафик:
Traceback (последний последний вызов):
Файл "/home/filmaster/django-trunk/django/core/handlers/base.py", строка 92, в ответ get_response = обратный вызов (запрос, * callback_args, ** callback_kwargs)
Файл "/home/filmaster/film20/film20/core/film_views.py", строка 193, в show_film
workflow.set_data_for_authenticated_user()Файл "/home/filmaster/film20/film20/core/film_views.py", строка 518, в set_data_for_authenticated_user
object_id = self.the_film.parent.id)Файл "/home/filmaster/film20/film20/core/film_helper.py", строка 179, в get_others_ratings
set_cache (CACHE_OTHERS_RATINGS, str (object_id) + "_" + str (user_id), userratings)Файл "/home/filmaster/film20/film20/utils/cache_helper.py", строка 80, в возврате set_cache cache.set(CACHE_MIDDLEWARE_KEY_PREFIX + full_path, result, get_time (cache_string))
Файл "/home/filmaster/django-trunk/django/core/cache/backends/memcached.py", строка 37, в наборе self._cache.set(smart_str (ключ), значение, таймаут или self.default_timeout)
Файл "/usr/lib/python2.5/site-packages/cmemcache.py", строка 128, в наборе val, flags = self._convert (Val)
Файл "/usr/lib/python2.5/site-packages/cmemcache.py", строка 112, в _convert val = pickle.dumps(val, 2)
PicklingError: Невозможно рассолчать: это не то же самое объект как decimal.Decimal
И исходный код для Filmaster можно скачать здесь: bitbucket.org/filmaster/filmaster-test
Любая помощь будет принята с благодарностью.
Я получил эту ошибку при работе в ноутбуке jupyter. Я думаю, проблема заключалась в том, что я использовал %load_ext autoreload
autoreload 2
. Перезапуск моего ядра и повторное использование решили проблему.
Одна странность Pickle заключается в том, что способ импортирования класса до того, как вы соберете один из его экземпляров, может тонко изменить маринованный объект. Pickle требует, чтобы вы импортировали объект одинаково как перед тем, как расчистить его, так и перед тем, как вы его разложите.
Итак, например:
from a.b import c
C = c()
pickler.dump(C)
сделает немного другой объект (иногда):
from a import b
C = b.c()
pickler.dump(C)
Попробуйте возиться с вашим импортом, это может исправить проблему.
Я продемонстрирую проблему с простыми классами Python в 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 not the same object as __main__.B
Эта ошибка показана потому, что мы пытаемся сбросить A, но поскольку мы изменили его имя для ссылки на другой объект "B", на самом деле pickle путают с тем объектом, который нужно сбросить - классом A или B. Очевидно, что специалисты по pickle очень умны и они уже проверили это поведение.
Решение. Проверьте, не конфликтует ли имя объекта, который вы пытаетесь сбросить, с другим объектом.
Я продемонстрировал отладку для случая, представленного выше, с ipython и ipdb ниже:
PicklingError: Can't pickle <class __main__.B at 0x7f4089235738>: it 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 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>
Я надеюсь, что это спасет некоторые головные боли! Adios !!
Я не могу объяснить, почему это тоже не удается, но мое собственное решение, чтобы исправить это, заключалось в том, чтобы изменить весь мой код на выполнение
from point import Point
к
import point
это одно изменение, и оно сработало. Я хотел бы знать, почему... hth
Вы каким-то образом reload(decimal)
, или monkeypatch десятичного модуля для изменения десятичного класса? Это две вещи, наиболее вероятно, создающие такую проблему.
При запуске процесса с multiprocessing
могут возникнуть проблемы, вызвав __init__
. Вот демо:
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))
Теперь, с приведенным выше кодом, если мы запустим это:
if __name__ == '__main__':
t = ProcessInitTest(spawn=True)
t.start_process_fail()
for i in range(1000):
t.do_square(i)
Мы получаем эту ошибку:
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 not the same object as __main__.__init__
И если мы изменим его на использование fork
вместо spawn
:
if __name__ == '__main__':
t = ProcessInitTest(spawn=False)
t.start_process_fail()
for i in range(1000):
t.do_square(i)
Мы получаем эту ошибку:
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'
Но если мы назовем метод start_process
, который не вызывает __init__
в целевом mp.Process
, например:
if __name__ == '__main__':
t = ProcessInitTest(spawn=False)
t.start_process()
for i in range(1000):
t.do_square(i)
Он работает как ожидалось (используем ли мы spawn
или fork
).
Моя проблема заключалась в том, что у меня была функция с одним и тем же именем, определенная дважды в файле. Так что, я думаю, это было смущено тем, что он пытался засолить.
То же самое случилось со мной
Перезапуск ядра работал у меня