假设我在文件myClass.py中有一个简单的python类定义
class Test:
A = []
Run Code Online (Sandbox Code Playgroud)
我还有两个测试脚本.第一个脚本创建一个Test类型的对象,填充数组A,并将结果pickle到文件.它立即从文件中取消它,并且仍然填充了数组.第二个脚本只是从文件中取消,并且没有填充数组(即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
Run Code Online (Sandbox Code Playgroud)
和test2.py
import myClass
import pickle
f = open('data')
y = pickle.load(f)
f.close
print y.A
Run Code Online (Sandbox Code Playgroud)
jdi*_*jdi 27
这是因为您将设置Test.A为类属性而不是实例属性.真正发生的事情是,使用test1.py,从pickle文件读回的对象与test2.py相同,但它使用最初分配的内存中的类x.A.
当您从文件中取消数据时,它会创建类类型的新实例,然后应用它需要的任何实例数据.但是您唯一的数据是类属性.它总是引用内存中的类,它在一个文件中修改,但在另一个文件中没有修改.
比较此示例中的差异:
class Test:
A = [] # a class attribute
def __init__(self):
self.a = [] # an instance attribute
Run Code Online (Sandbox Code Playgroud)
您会注意到实例属性a将被正确地pickle和unpickled,而class属性A将简单地引用内存中的类.
for i in xrange(5):
x.A.append(i)
x.a.append(i)
with open('data', 'w') as f:
pickle.dump(x,f)
with open('data') 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
[]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29067 次 |
| 最近记录: |