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

问题描述 投票:1回答:1

假设我们想要序列化下面的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-idiomatic方式来执行这样的事情?

python serialization deserialization
1个回答
2
投票

借用pickle的dunders:

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而不是其中一个。

© www.soinside.com 2019 - 2024. All rights reserved.