36

ファイル myClass.py に単純な python クラス定義があるとします。

class Test:
    A = []

また、2 つのテスト スクリプトもあります。最初のスクリプトは、Test 型のオブジェクトを作成し、配列 A に値を入力して、結果をファイルにピクルします。ファイルからすぐに unpickle し、配列にはまだ値が設定されています。2 番目のスクリプトは、ファイルから unpickle するだけで、配列にはデータが取り込まれません (つまり、A == [])。どうしてこれなの?

test1.py

import myClass
import pickle

x = myClass.Test()

for i in xrange(5):
    x.A.append(i)

f = open('data', 'w')
pickle.dump(x,f)
f.close()

f = open('data')
y = pickle.load(f)
f.close

print y.A

およびtest2.py

import myClass
import pickle

f = open('data')
y = pickle.load(f)
f.close

print y.A
4

2 に答える 2

41

Test.Aこれは、インスタンス属性ではなくクラス属性として設定しているためです。実際に起こっていることは、test1.pyでは、pickleファイルから読み戻されるオブジェクトはtest2.pyと同じですが、最初に割り当てたメモリ内のクラスを使用しているということですx.A

データがファイルから選択解除されると、クラスタイプの新しいインスタンスが作成され、必要なインスタンスデータが適用されます。しかし、あなたの唯一のデータはクラス属性でした。常に、あるファイルで変更したが別のファイルでは変更しなかった、メモリ内のクラスを参照します。

この例の違いを比較してください。

class Test:
    A = []  # a class attribute
    def __init__(self):
        self.a = []  # an instance attribute

インスタンス属性aは適切にピクルス化およびアンピクルス化されますが、クラス属性Aは単にメモリ内のクラスを参照します。

for i in range(5):
    x.A.append(i)
    x.a.append(i)  

with open('data', 'wb') as f:
    pickle.dump(x,f)

with open('data', 'rb') as f:
    y = pickle.load(f)

>>> y.A
[0, 1, 2, 3, 4]
>>> y.a
[0, 1, 2, 3, 4]
>>> Test.A
[0, 1, 2, 3, 4]
>>> Test.A = []  # resetting the class attribute
>>> y.a 
[0, 1, 2, 3, 4]
>>> y.A  # refers to the class attribute
[]
于 2012-05-31T23:29:10.830 に答える