Python继承模式 - 如何处理反序列化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python继承模式 - 如何处理反序列化相关的知识,希望对你有一定的参考价值。
假设我们想要序列化下面的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方式来执行这样的事情?
答案
借用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
而不是其中一个。
以上是关于Python继承模式 - 如何处理反序列化的主要内容,如果未能解决你的问题,请参考以下文章