当我们要反序列化一个之前版本的序列化结果时,我们希望能正确的反序列化并使用我们提供的默认值作为最终的反序列化值 。这在属性A.b的测试中得到了体现 。
(上面的测试有很多边界的情况、支持的变量类型并没有覆盖,此测试只是作为示例使用 。)
如果能有一个类可以让上面的测试通过,相信那个类就是我们所需要的类了 。这样的类可以实现为如下:
def is_normal_prop(obj, key):is_prop = isinstance(getattr(type(obj), key, None), property)is_func_attr = callable(getattr(obj, key))is_private_attr = key.startswith('__')return not (is_func_attr or is_prop or is_private_attr)def is_basic_type(value):return value is None or type(value) in [int, float, str, bool]class JsonSerializable:def _serialize_prop(self, name):return getattr(self, name)def _as_dict(self):props = {}for key in dir(self):if not is_normal_prop(self, key):continuevalue = self._serialize_prop(key)if not (is_basic_type(value) or isinstance(value, JsonSerializable)):raise Exception('unknown value to serialize to dict: key={}, value={}'.format(key, value))props[key] = value if is_basic_type(value) else value._as_dict()return propsdef serialize(self):return json.dumps(self._as_dict(), ensure_ascii=False)def _deserialize_prop(self, name, deserialized):setattr(self, name, deserialized)@classmethoddef deserialize(cls, json_encoded):if json_encoded is None:return Noneargs = inspect.getfullargspec(cls)args_without_self = args.args[1:]obj = cls(*([None] * len(args_without_self)))data = json.loads(json_encoded, encoding='utf8') if type(json_encoded) is str else json_encodedfor key in dir(obj):if not is_normal_prop(obj, key):continueif key in data:obj._deserialize_prop(key, data[key])return obj在实现时,我们利用了Python的内省机制,这样就可以自动的识别对象的属性及运行时类型了 。当然对于这个简单的类还有很多待支持的功能,使用上也有很多限制,比如:
- 当某一属性为自定义类的类型的时候,需要子类覆盖实现_deserialize_prop方法为反序列化过程提供支持
- 当某一属性为由自定义类构成的一个list tuple dict复杂对象时,需要子类覆盖实现_deserialize_prop方法为反序列化过程提供支持
- 简单属性必须为python内置的基础类型,比如如果某一属性的类型为numpy.float64,序列化反序列化将不能正常工作
到这里这个基类就差不多可以支撑我们日常的开发需要了 。当然对于这个简单的实现还有可能有其他的需求或者问题,大家如有发现,欢迎留言交流 。
文/ThoughtWorks廖光明
推荐阅读
- 教你在几分钟内构建一个Python包
- 紧压茶如何审评,哪些人不宜食用紧压茶
- 海红马茶的功效及贮藏,如何储存雨花茶的鲜爽风味
- 菊花茶如何泡,喝菊花茶的注意事项
- 浏览器内容如何保存?
- 微信群总是有人发广告?看我用Python写一个机器人消灭他
- 素颜霜的正确使用方法是什么?
- 简单网络的反向传播代码这么写就对了:分解步骤+完整实现
- 老茶头如何保存好,什么样的老茶头比较好
- 左右沙发怎么样 左右沙发如何挑选
