PicklingError: Невозможно засечь <class 'decimal.Decimal'>: это не тот же объект, что и decimal.Decimal

Это ошибка, которую я получил сегодня на http://filmaster.com "> filmaster.com:

PicklingError: Не могу засолить: это не тот же объект, что и десятичный. Десятичный

Что это значит? Кажется, это не имеет большого смысла ... Похоже, это связано с кэшированием в 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), пользовательские настройки)

Файл "/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: Не могу засолить: это не тот же объект, что и десятичный. Десятичный

И исходный код для Filmaster можно скачать здесь:bitbucket.org/filmaster/filmaster-test

Любая помощь будет оценена.

 dbn08 дек. 2017 г., 00:03
Я также видел это с декораторами классов, в частности, six.add_metaclass
 partofthething08 янв. 2013 г., 02:33
Я получил похожую ошибку после написания ошибочногоGetState метод для объекта, чтобы изменить его поведение рассола. Не уверен, в чем проблема, но проверьте любой из них.

Ответы на вопрос(6)

что способ импорта класса перед тем, как выбрать один из его экземпляров, может слегка изменить выбранный объект. Pickle требует, чтобы вы импортировали объект идентично как до того, как вы это сделаете, так и до того, как вы его удалите.

Так, например:

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

создаст слегка другой объект (иногда) для:

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

Попробуйте поиграть с импортом, это может решить проблему.

 michuk17 янв. 2010 г., 03:59
так почему же эта проблема с травлением возникает только один раз в тысячах запросов, и обычно она работает нормально?

reload(decimal)или monkeypatch десятичный модуль, чтобы изменить десятичный класс? Это две вещи, которые могут вызвать такую проблему.

 michuk17 янв. 2010 г., 03:58
Нет, ничего такого. Я только импортирую десятичный класс.

почему это не помогает, но мое собственное решение, чтобы исправить это, состояло в том, чтобы изменить весь мой код от выполнения

from point import Point

в

import point

это одно изменение, и это сработало. Я хотел бы знать, почему ...

 sanchitarora04 мар. 2019 г., 19:16
Это также помогло мне, и я хотел бы знать, почему!

что проблема заключалась в том, что я использовал%load_ext autoreload autoreload 2, Перезапуск моего ядра и повторный запуск решили проблему.

 theindigamer01 дек. 2017 г., 16:02
Кажется, что изменение метода класса является причиной проблемы. Я думаю, чтоautoreload не обновляет определение, сохраненное в другом месте. Перезапуск исправил бы это, потому что более новое определение загружено в обоих местах.

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

Эта ошибка показана потому, что мы пытаемся сбросить A, но поскольку мы изменили его имя, чтобы ссылаться на другой объект «B», pickle на самом деле путают с тем, какой объект сбросить - класс A или B. Очевидно, что специалисты по pickle очень умны и они уже проверили это поведение.

Решение: Проверьте, не конфликтует ли имя объекта, который вы пытаетесь сбросить, с другим объектом.

Я продемонстрировал отладку для случая, представленного выше, с ipython и ipdb ниже:

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>

Я надеюсь, что это спасет некоторые головные боли! Adios !!

начиная процесс с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's 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).

Ваш ответ на вопрос