Python Pickling变量仅在超类中

时间:2013-10-11 20:03:24

标签: python

如何挑选对象的子类,但只捕获其超类的变量(并将对象转换为超类)。

我这样做的原因是因为我有额外的信息需要创建我的“课堂”,但在阅读时需要一个轻量级的版本。

示例:

import cPickle
def unpickle_me(filename):
    myobj= cPickle.load( open( filename, "rb" ) )
    return myobj

def pickle_me(obj, filename):
    cPickle.dump(obj, open( filename, "wb" ) )

class A(object):
    def __init__(self):
        self.a = []

    def read_index(self, index):
        return self.a[index]

class B(A): 
    def __init__(self, b):
        super(B, self).__init__()
        self.b = b; # let b = 3 for example

    def add_to_super(self, avar):
        self.a.append(avar*self.b)

classB = B(3)
classB.add_to_super(5)
pickle_me(classB, 'me_b.pickle')
myobj = unpickle_me('me_b.pickle')
print(type(myobj), myobj.__dict__) 
>>>> (<class '__main__.B'>, {'a': [15], 'b': 3})

所以酸洗工作!它腌制了我的期望。但实际上,我想要的更像是:

pickle_me(classB, 'me_b.pickle')
myobj = unpickle_me('me_b.pickle')
print(type(myobj), myobj.__dict__)
>>>> (<class '__main__.A'>, {'a': [15]})  # class A and only has A

作为奖励,无论谁打开它,都不能通过我的“add_to_super”将另一个值“附加”给A。

问题: 1.有办法做到这一点吗?我愿意在A类和B类中编写__ getstate __信息。

  1. 如果我使用__ getstate __,有没有办法自动保存我在A类中指定的变量?所以我不需要说del self。 __ dict __ ['b']

  2. 我可以编写一个特殊方法,允许我选择我想要的版本吗?,比如只选择泡菜信息或泡菜B信息(当给出B类时)

  3. 附带问题:在这种情况下我需要定义__ setstate __吗?或者单独使用__ getstate __?

  4. 此外,我意识到OO的结构很糟糕,并且不介意任何关于它的指示。

2 个答案:

答案 0 :(得分:0)

我认为最干净的解决方案是将B转化为A,然后再进行腌制(如果您只想挑选A个信息)。

class B(A):
    def to_A(self):
        a = A()
        a.a = self.a
        return a

然后,当您取消此功能时,您将获得所需的A

对我来说,像这样的明确解决方案比编写一个花哨的酸洗界面更好。

关于您的第4点(OO结构),您的B类称为 factory 。通常,工厂可以方便地使用这种API:

factory = MyFactory()
factory.set_some_parameters(...)
factory.set_some_other_parameters(...)
A1 = factory.construct_A()
A2 = factory.construct_A()

答案 1 :(得分:0)

您可以使用__reduce__协议指定要腌制的内容而不是您的课程实例,__setstate____getstate__始终对原始课程进行操作。因此,如果您希望在A的实例时挑选B的实例,它可能如下所示:

class B(A): 
    def __init__(self, b):
        super(B, self).__init__()
        self.b = b; # let b = 3 for example

    def add_to_super(self, avar):
        self.a.append(avar*self.b)

    def __reduce__(self):
        return A, (), {'a': self.a}