2

カスタム クラスのインスタンスをピクルしようとしています。このクラスには、ウィジェット オブジェクトのリストを含む「ウィジェット」という属性があります。コンテナーをピクルすると、リストが失われます。オブジェクト内のリストをピクルすることはできませんか?

import pickle

filename = 'container.pkl'

class Container(object):
    widgets = []

class Widget(object):
    pass

c = Container()
c.name = "My Container"

w = Widget()
w.name = "My Widget"

c.widgets.append(w)

data = open(filename, 'wb')
pickle.dump(c, data)
data.close()

後で私は解凍しようとします...

# assume I have imported the classes and filename here

data = open(filename, 'rb')
container = pickle.load(data)
data.close()


print container.name # shows the pickled name
print container.widgets # shows []

pickle と cPickle を試してみましたが、結果は同じでした。

4

3 に答える 3

7

widgetsクラスのインスタンスの属性ではなく、クラス 属性です。インスタンスをピクルしたとき、クラス属性はピクルせず、インスタンス属性だけをピクルしました。したがって、ピクルを解除すると、インスタンス属性だけが返されます。ContainerContainer

Python ドキュメントのインスタンス属性とクラス属性について読む必要があります。

ウィジェットもピクルしたい場合は、リストをクラス属性ではなくインスタンス属性にする必要があります。次に例を示します。

import pickle

filename = 'container.pkl'

class Container(object):
    def __init__(self, name):
        self.name = name
        self.widgets = []

class Widget(object):
    def __init__(self, name):
        self.name = name

c = Container('My Container')
w = Widget('My Widget')

c.widgets.append(w)

data = open(filename, 'wb')
pickle.dump(c, data)
data.close()
于 2013-08-21T15:51:43.533 に答える
0

Python 内で List オブジェクトをピクルすることは間違いなく可能です。__getstate__使用しているカスタム クラスがandメソッドをオーバーライドしている可能性があります。この場合__setstate__、開発者は、そのクラスの pickle 化/非 pickle 化する属性のセットからウィジェット リストを削除して、widget リストを pickle 化しないことにしました。

詳細については、こちらを参照してください。このカスタム クラスのソース コードを観察して、実際にそうであるかどうかを確認できるとよいでしょう。

于 2013-08-21T15:42:58.480 に答える
0

問題は、ウィジェットがクラス属性であり、ピクルされていないことです。Container.widgets はすでに必要なものであるため、同じセッションで unpickle すると、スクリプトが機能するように見えます。Container.widgets が設定されていないため、新しいセッションを開始しても機能しません。

于 2013-08-21T15:52:25.520 に答える