Python中静态可序列化类变量

4
在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个回答

4

引用"什么可以被pickle和unpickle?"部分的内容:

Similarly, classes are pickled by named reference, so the same restrictions in the unpickling environment apply. Note that none of the class’s code or data is pickled, so in the following example the class attribute attr is not restored in the unpickling environment:

class Foo:
    attr = 'a class attr'

picklestring = pickle.dumps(Foo)
因为attr,或者在你的情况下是count,是类定义的一部分,所以它永远不会被pickle。在你的“write”示例中,你打印了存在但从一开始就没有被pickle的Sample.count
你可以将Sample.count存储在每个实例中作为_count,并放置Sample.count = self._count。但请记住,由于你的d是一个dict,它们可能以任何顺序unpickle。因此,基本上这行不通。
你需要添加__setstate__到你的类中来自定义它pickle的方式,并放入一些标志值(比如_count),然后在__getstate__中通过任何一致的逻辑进行操作。(编辑:除非你将count存储在全局变量中,在getstate中访问它并在每次解pickle对象时进一步操作,否则无法解决给定问题。)
另一个潜在的解决方法,但很糟糕:向你的dict d添加一个变量,以便它也被pickled。当你读回来时,用Sample.count=d['_count']恢复。因此,在pickle时,pickle.dump(d,f)之前,要执行d['_count']=Sample.count

重要的警告:这实际上并没有让您pickle Sample.count ,因为您实际上正在pickle(d)的是Sample的字典。

编辑: Sample.count = len(d.values()) ,您将其作为解决方法放置的内容非常具体,不适用于一般的类属性。


我知道类变量无法被pickle。我已经编辑了我的问题并提供了另一种解决方案。 - Dr. Debasish Jana
添加了一条关于它的评论以及一个解决方法,因为您实际上正在对“Sample”的“dict”进行腌制...这为您的问题提供了一个简单的解决方法。 - aneroid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接