Подтвердить что ты не робот

PicklingError: не может pickle <class 'decimal.Decimal'>: это не тот же объект, что и decimal.Decimal

Это ошибка, которую я получил сегодня на 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

Любая помощь будет принята с благодарностью.

4b9b3361

Ответ 1

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

Ответ 2

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

Итак, например:

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

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

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

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

Ответ 3

Я продемонстрирую проблему с простыми классами 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 !!

Ответ 4

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

from point import Point

к

import point

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

Ответ 5

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

Ответ 6

При запуске процесса с 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).

Ответ 7

Моя проблема заключалась в том, что у меня была функция с одним и тем же именем, определенная дважды в файле. Так что, я думаю, это было смущено тем, что он пытался засолить.

Ответ 8

То же самое случилось со мной

Перезапуск ядра работал у меня