web-dev-qa-db-ja.com

PicklingError:<class 'decimal.Decimal'>をピクルできません:decimal.Decimalと同じオブジェクトではありません

これは本日http://filmaster.com "> filmaster.comで発生したエラーです。

PicklingError:ピクルできません:decimal.Decimalと同じオブジェクトではありません

それはどういう意味ですか?それは多くの意味をなさないようです...それはDjangoキャッシングと接続されているようです。ここでトレースバック全体を見ることができます:

トレースバック(最新の呼び出しが最後):

ファイル「/home/filmaster/Django-trunk/Django/core/handlers/base.py」の92行目のget_responseレスポンス= callback(request、* callback_args、** callback_kwargs)

Show_filmのファイル「/home/filmaster/film20/film20/core/film_views.py」、193行目
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)

Get_others_ratingsのファイル「/home/filmaster/film20/film20/core/film_helper.py」の179行目
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(key)、value、timeout or self.default_timeout)

ファイル「/usr/lib/python2.5/site-packages/cmemcache.py」、128行目、set 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

どんな助けでも大歓迎です。

37
michuk

Jupyterノートブックで実行すると、このエラーが発生しました。問題は、私が%load_ext autoreloadautoreload 2。カーネルを再起動して再実行すると問題は解決しました。

56
James Owers

Pickleの奇妙な点の1つは、クラスのインスタンスの1つをpickleする前にクラスをインポートする方法で、pickleされたオブジェクトを微妙に変更できることです。ピクルでは、ピクルする前とピクルする前に、オブジェクトを同じようにインポートする必要があります。

だから例えば:

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

微妙に異なるオブジェクトを(時々)作成します:

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

インポートをいじってみてください。問題が修正される可能性があります。

24
Salim Fadhley

簡単な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's not the same object as __main__.B

このエラーは、Aをダンプしようとしているために表示されますが、別のオブジェクト「B」を参照するように名前を変更したため、pickleは実際にダンプするオブジェクトと混同されています-クラスAまたはB。彼らはすでにこの振る舞いをチェックしています。

解決策:ダンプしようとしているオブジェクトの名前が別のオブジェクトと競合していないかどうかを確認します。

私は上記のケースのデバッグを以下の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>

これが頭痛の種を救ってくれることを願っています!アディオス!!

9
Saim Raza

これも失敗している理由を説明することはできませんが、これを修正するための私の独自の解決策は、すべてのコードを変更することでした

from point import Point

import point

この1つの変更とそれが機能しました。理由を教えてください。

5
Neil McGill

__init__を呼び出すと、multiprocessingでプロセスを開始するときに問題が発生する可能性があります。ここにデモがあります:

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を使用しているかどうか)。

4
caleb

どういうわけかreload(decimal)、またはDecimalクラスを変更するためにdecimalモジュールをモンキーパッチしましたか?これらは、このような問題を引き起こす可能性が最も高い2つのものです。

3
Antoine P.

私の問題は、同じ名前の関数がファイルで2回定義されていることでした。だから、どれを漬けようとしたのか混乱していたと思います。

1
Alexei Andreev

同じことが私にも起こりました

カーネルを再起動するとうまくいきました

0
Tina

デバッグ中に同じ問題が発生しました(Spyder)。プログラムを実行すると、すべてが正常に機能しました。しかし、デバッグを開始すると、picklingErrorに直面しました。

しかし、オプション専用コンソールで実行をファイルごとの実行構成(ショートカット:ctrl + F6)で選択すると、すべて正常に機能しました。それがどのように適応しているかは正確にはわかりません。

注:私のスクリプトでは、次のような多くのインポートがあります

from PyQt5.QtWidgets import *
from PyQt5.Qt import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import os, sys, re, math

私の基本的な理解は、スター(*)のため、このpicklingErrorを受け取っていたということです。

0
Rohithsai Sai