如何使用pickle()初始化实例?

时间:2012-06-28 12:14:06

标签: python

我想定义一个能够从另一个实例的序列化数据中读取自身的类。这是简化的代码:

class MyClass(list):

    def __init__(self,**kwargs):
        if kwargs.has_key('fdata'):
            f = open(kwargs['fdata'],'r')
            self = pickle.load(f)
            print len(self)    #prints 320          
            f.close()              

    ...

a = MyClass(fdata='data.dat')
print len(a)    #prints 0

这是我获得的输出:

320
0

我遇到的问题是返回的实例总是空的,即使我能够读取__init__()内的所有元素可能导致这种情况?

2 个答案:

答案 0 :(得分:4)

在方法内部分配self只需将本地名称self重新绑定到其他对象。在Python中对裸名称的赋值永远不能修改任何对象 - 它们只是重新绑定名称。

为什么不使用直截了当的

with open("data.dat") as f:
    a = pickle.load(f)

而不是构建一个新类?如果您不喜欢这样,请将其包装在一个函数中,但将此代码放入__init__()并不是很有用。

还有其他方法可以达到同样的效果。实现您正在尝试的最佳方法可能是覆盖__new__()而非__init__() - __new__()在构建新实例之前被称为,因此您可以简单地返回unpickled实例,而不必修改已构造的实例。

答案 1 :(得分:3)

self是Python中的常规局部变量。您不能使用self = other使对象“成为”其他东西,您只需重新分配本地。您必须逐个恢复属性,或使用以下内容:

self.__dict__ = pickle.load(f).__dict__

(我没有测试过最后一行,它可能会让你的小猫爆炸。)