【问题标题】:Serializable Static class variables in PythonPython中的可序列化静态类变量
【发布时间】:2016-03-24 22:18:40
【问题描述】:

是否可以在 python 中具有可序列化的静态类变量或方法? 例如假设,我有以下代码 sn-p:

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

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

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

现在的输出是:

Sample.count = 10

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

【问题讨论】:

    标签: python class serialization static class-variables


    【解决方案1】:

    引用"What can be pickled and unpickled?"上的部分

    同样,类是通过命名引用来腌制的,因此在 unpickling 环境中也适用相同的限制。请注意,没有任何类的代码或数据被腌制,因此在以下示例中,类属性 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 中访问该变量并在每次取消对象时进一步操作,否则对给定问题没有帮助。)

    另一个可能的解决方法,但 糟糕:将变量添加到您的 dict d 以便它也被腌制。回读时,使用Sample.count = d['_count'] 恢复。所以在pickle.dump(d,f)之前,当你腌制的时候,做d['_count'] = Sample.count

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

    编辑:您作为解决方法提供的Sample.count = len(d.values()) 对于您的用例非常特定,而不是 general 中的类属性。

    【讨论】:

    • 我知道类变量不能腌制。使用替代解决方案编辑任何问题
    • 添加了一个关于它的评论和一个你可以使用的解决方法,因为你实际上是在酸洗 dictSamples ......这可以轻松解决你的问题。
    猜你喜欢
    • 2012-10-31
    • 1970-01-01
    • 2018-08-08
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    相关资源
    最近更新 更多