Python中的Serializable Static类变量

时间:2015-12-18 08:48:51

标签: python class serialization static class-variables

是否可以在python中使用可序列化的静态类变量或方法? 举个例子,我有以下代码片段:

import pickle
class Sample:
    count = 0 # class variable
    def __init__(self, a1=0, a2=0):
        self.a = a1
        self.b = a2
        Sample.count += 1

#MAIN
f = open("t1.dat", "wb")
d = dict()
for i in range(10):
    s = Sample(i, i*i)
    d[i] = s
pickle.dump(d,f)
print "Sample.count = " + str(Sample.count)
f.close()

输出结果为:

Sample.count = 10

现在,我有另一个与上面类似的读者程序:

import pickle
class Sample:
    count = 0 # class variable
    def __init__(self, a1=0, a2=0):
        self.a = a1
        self.b = a2
        Sample.count += 1

#MAIN
f = open("t1.dat", "rb")
d = pickle.load(f)
print "Sample.count = " + str(Sample.count)

输出结果为:

Sample.count = 0

我的问题是: 如何从我的文件加载类变量?换句话说,我如何序列化一个类变量?如果直接不可能,还有其他选择吗?请建议。 由于无法选择类变量,作为替代方案,我在从文件中读取时使用了主要部分中的代码片段,如下所示:

#MAIN
f = open("t1.dat", "rb")
d = pickle.load(f)
Sample.count = len(d.values())
print "Sample.count = " + str(Sample.count)

输出现在是:

Sample.count = 10

是否可以接受解决方案?还有其他选择吗?

1 个答案:

答案 0 :(得分:3)

引用"What can be pickled and unpickled?"

上的部分
  

类似地,类通过命名引用进行pickle,因此适用于unpickling环境中的相同限制。请注意,没有类的代码或数据被pickle,因此在下面的示例中,类属性attr不会在unpickling环境中恢复:

class Foo:
    attr = 'a class attr'

picklestring = pickle.dumps(Foo)

因为attr或者在你的情况count中,它是类定义的一部分,所以它永远不会被腌制。在你的写作'例如,您打印的Sample.count确实存在但首先没有被腌制。

您可以将Sample.count存储在每个实例中_count并放置Sample.count = self._count。但请记住,由于您的ddict,因此它们可能会以任何顺序展开。所以基本上这不会起作用。

你需要在你的班级中添加__setstate__来自定义它的方式并加入一些标志值(如_count)然后你操纵(通过任何逻辑工作)始终如一地在__getstate__(编辑:不帮助解决给定的问题,除非您将count存储在全局变量中并访问getstate并进一步操作每次对象被打开时。)

另一种潜在的解决方法,但 yuck :向dict d添加一个变量,以便它也被腌制。当您阅读它时,请使用Sample.count = d['_count']进行恢复。因此,在pickle.dump(d,f)腌制之前,请d['_count'] = Sample.count

重要警告:这实际上并不允许您挑选Sample.count,因为您实际上正在腌制(d)是Sample的字典。

修改:您作为变通方法的Sample.count = len(d.values())非常特定于您的用例而不是 general < / em>的