Python继承模式-如何处理反序列化

时间:2018-06-29 18:35:07

标签: python serialization deserialization

说我们要在下面序列化B

import json
class A:
    def __init__(self):
        self.a = 1
    @classmethod
    def serialize(cls, t):
        with open('temp_A.json', 'wb') as f:
            json.dump({'a':t.a}, f)
    @classmethod
    def deserialize(cls):
        with open('temp_A.json', 'rb') as f:
            d = json.load(f)
            obj = A()
            obj.a = d['a']
            return obj

class B(A):
    def __init__(self):
        super(B, self).__init__()
        self.b = 2
    @classmethod
    def serialize(cls, t):
        with open('temp_B.json', 'wb') as f:
            json.dump({'b':t.b}, f)
    @classmethod
    def deserialize(cls):
        with open('temp_B.json', 'rb') as f:
            d = json.load(f)
            obj = B()
            obj.b = d['b']
            a = A.deserialize()
            #### IMPORTANT: doesn't work
            super(B, b) = a
            ####
            return b

如果此序列化模式很糟糕并且您有其他选择,请告诉我。但是,在当前阶段,我不确定如何将超类的成员变量重新分配为a的属性(因为a的状态可能与初始构造期间不同)。我知道我可以做类似super(B,b).__dict__ = a.__dict__的事情,但是感觉不对。 执行这种操作的python惯用方式是什么?

1 个答案:

答案 0 :(得分:2)

pickle借来钱财:

import json
class A:
    def __init__(self):
        self.a = 1

    def __getstate__(self):
        return {'a': self.a}

    def __setstate__(self, state):
        '''Accepts a json/dict, sets member attributes accordingly'''
        self.a = state['a']

    def serialize(self):
        return json.dumps(self.__getstate__())

    @classmethod
    def deserialize(cls, json_str):
        d = json.loads(json_str)
        obj = cls()
        obj.__setstate__(d)
        return obj

class B(A):
    def __init__(self):
        super(B, self).__init__()
        self.b = 2

    def __setstate__(self, state):
        '''Accepts a json/dict, sets member attributes accordingly'''
        super().__setstate__(state)
        self.b = state['b']

    def __getstate__(self):
        state = super().__getstate__()
        state.update({'b': self.b})  # or state['b'] = self.b
        return state

    def serialize(self):
        return json.dumps(self.__getstate__())

    @classmethod
    def deserialize(cls, json_str):
        d = json.loads(json_str)
        obj = cls()
        obj.__setstate__(d)
        return obj


# Test A roundtrip
a1 = A()
a1_str = a1.serialize()
print(a1_str)               # {"a": 1}

a2 = A.deserialize(a1_str)
a2_str = a2.serialize()
print(a2_str)               # {"a": 1}

print(a1_str == a2_str)     # True

# Test B roundtrip
b1 = B()
b1_str = b1.serialize()
print(b1_str)               # {"a": 1, "b": 2}

b2 = B.deserialize(b1_str)
b2_str = b2.serialize()
print(b2_str)               # {"a": 1, "b": 2}

print(b1_str == b2_str)     # True

这里还有其他一些更改,例如不对deserialize()类方法中的类名进行硬编码,将其序列化为字符串而不是文件(用于测试),使用一致的dumps / loads而不是每个。

相关问题