0

如何腌制对象的子类,但仅捕获其超类的变量(并将对象转换为超类)。

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

例子:

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。__ 字典 __ ['b']

  2. 我可以写一个特殊的方法来让我选择我想要的版本吗?比如仅泡菜 A 信息或泡菜 B 信息(当给定 B 类时)

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

  4. 我也意识到这里的面向对象的结构很糟糕,并且不介意任何指针。

4

2 回答 2

0

我认为最干净的解决方案是在腌制之前将其转换BA(如果您只想腌制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()
于 2013-10-11T20:09:36.743 回答
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}
于 2013-10-11T20:12:37.490 回答