Ret*_*sam 1 python serialization pickle
我正在尝试使用pickle来保存自定义类; 与下面的代码非常相似的东西(虽然在类上定义了一些方法,还有几个dicts等数据).但是,通常当我运行它,pickle然后unpickle时,我会丢失类中的所有数据,并且就好像我创建了一个新的空白实例.
import pickle
class MyClass:
VERSION = 1
some_data = {}
more_data = set()
def save(self,filename):
with open(filename, 'wb') as f:
p = pickle.Pickler(f)
p.dump(self)
def load(filename):
with open(filename,'rb') as ifile:
u = pickle.Unpickler(ifile)
obj = u.load()
return obj
Run Code Online (Sandbox Code Playgroud)
我想知道这是否与泡菜类的备忘录有关,但我觉得不应该这样做.当它不起作用时,我会查看我生成的文件,它看起来像这样:(显然不是可读的,但它显然不包含数据)
€c__main__ MyClass q
无论如何,我希望这足以让某人了解这里可能会发生什么,或者看什么.
您遇到的问题是您使用可变类变量来保存数据,而不是将数据放入实例变量中.
该pickle模块仅保存直接存储在实例上的数据,而不保存也可通过其访问的类变量self.当您发现未修改的实例没有数据时,这可能意味着该类不保存上一次运行的数据,因此实例无法再访问它.
使用类变量也可能会导致其他问题,因为数据将由类的所有实例共享!这是一个说明问题的Python控制台会话代码:
>>> class Foo(object):
class_var = []
def __init__(self, value):
self.class_var.append(value)
>>> f1 = Foo(1)
>>> f1.class_var
[1]
>>> f2 = Foo(2)
>>> f2.class_var
[1, 2]
Run Code Online (Sandbox Code Playgroud)
这可能不是你想要的.但它变得更糟!
>>> f1.class_var
[1, 2]
Run Code Online (Sandbox Code Playgroud)
您认为属于的数据f1已被创建更改f2.实际上,它是f1.class_var完全相同的对象f2.class_var(它也可以通过Foo.class_var直接获得,而不需要经过任何实例).
所以,使用类变量几乎肯定不是你想要的.相反,__init__为创建新值的类编写一个方法并将其保存为实例变量:
>>> class Bar(object):
def __init__(self, value):
self.instance_var = [] # creates a separate list for each instance!
self.instance_var.append(value)
>>> b1 = Bar(1)
>>> b1.instance_var
[1]
>>> b2 = Bar(2)
>>> b2.instance_var # doesn't include value from b1
[2]
>>> b1.instance_var # b1's data is unchanged
[1]
Run Code Online (Sandbox Code Playgroud)
Pickle会像你期望的那样处理这个课程.它的所有数据都在实例中,因此当你unpickle时你永远不应该得到一个空的实例.
| 归档时间: |
|
| 查看次数: |
570 次 |
| 最近记录: |