LoginSignup
2
1

More than 5 years have passed since last update.

pickleでエラーが発生する特殊なケース

Posted at

pickleは、ファイルなどに保存するために、Python オブジェクトをバイト列にシリアライズするための標準ライブラリです。

どのようなオブジェクトがpickleできるかはpickleのレファレンスに記述がありますが、相互に参照しているオブジェクトがうまくunpickle出来ない現象が起きたので調べたところ、こちらのイシュートラッカーにあるとおり未解決の問題があるようです。

次のスクリプトを実行すると、pickle.loadsでunpickleする際に、AttributeError: 'Node' object has no attribute 'i'となります。

# modified from https://bugs.python.org/file2428/circle.py

import pickle

class Node(object):
    def __init__(self, i):
        self.i = i

    def __cmp__(self, other):
        return cmp(self.i, other.i)

    def __hash__(self):
        return hash(self.i)

n = Node(12)
n.next_nodes = set((n,))

byteobj = pickle.dumps(n)
unpickled = pickle.loads(byteobj)

このエラーが起こるのは、Nodeオブジェクトのnが次の条件にあてはまるからで、このような条件にあてはまるオブジェクトはpickle/unpickle出来ない可能性があります。

  • __hash__メソッドで、自らのメンバーiを使用している。
  • nは、n.next_nodessetオブジェクトの要素として、自らを循環参照している。
  • 循環参照の過程で、(setの要素であるから)__hash__メソッドが使用されている

2007年に報告されたバグですが、イシュートラッカーでは、レアなケースだし、修正するのは大変なので修正しないと開き直っており、未だ解決されていないようです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1