电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

利用Python實現Json序列化庫的方法步驟

瀏覽:3日期:2022-07-11 18:16:26

前言

在Python的世界里,將一個對象以json格式進行序列化或反序列化一直是一個問題。Python標準庫里面提供了json序列化的工具,我們可以簡單的用json.dumps來將一個對象序列化。但是這種序列化僅支持python內置的基本類型。

利用Python實現Json序列化庫的方法步驟Python

在Python的世界里,將一個對象以json格式進行序列化或反序列化一直是一個問題。Python標準庫里面提供了json序列化的工具,我們可以簡單的用json.dumps來將一個對象序列化。但是這種序列化僅支持python內置的基本類型,對于自定義的類,我們將得到Object of type A is not JSON serializable的錯誤。

有很多種方法可以用來支持這種序列化,這里有一個很長的關于這個問題的討論。總結起來,基本上有兩種還不錯的思路:

利用標準庫的接口:從python標準json庫中的JSONDecoder繼承,然后自定義實現一個default方法用來自定義序列化過程 利用第三方庫實現:如jsonpickle jsonweb json-tricks等

利用標準庫的接口的問題在于,我們需要對每一個自定義類都實現一個JSONDecoder.default接口,難以實現代碼復用。

利用第三方庫,對我們的代碼倒是沒有任何侵入性,特別是jsonpickle,由于它是基于pickle標準序列化庫實現,可以實現像pickle一樣序列化任何對象,一行代碼都不需要修改。

但是我們觀察這類第三方庫的輸出的時候,會發現所有的這些類庫都會在輸出的json中增加一個特殊的標明對象類型的屬性。這是為什么呢?Python是一門動態類型的語言,我們無法在對象還沒有開始構建的時候知道對象的某一屬性的類型信息,為了對反序列化提供支持,看起來確實是不得不這么做。

有人可能覺得這也無可厚非,似乎不影響使用。但是在跨語言通信的時候,這就成為了一個比較麻煩的問題。比如我們有一個Python實現的API,客戶端發送了一個json請求過來,我們想在統一的一個地方將json反序列化為我們Python代碼的對象。由于客戶端不知道服務器端的類型信息,json請求里面就沒法加入這樣的類型信息,這也就導致這樣的類庫在反序列化的時候遇到問題。

能不能有一個相對完美的實現呢?先看一下我們理想的json序列化庫的需求:

我們希望能簡單的序列化任意自定義對象,只添加一行代碼,或者不加入任何代碼 我們希望序列化的結果不加入任何非預期的屬性 我們希望能按照指定的類型進行反序列化,能自動處理嵌套的自定義類,只需要自定義類提供非常簡單的支持,或者不需要提供任何支持 我們希望反序列化的時候能很好的處理屬性不存在的情況,以便在我們加入某一屬性的時候,可以設置默認值,使得舊版本的序列化結果可以正確的反序列化出來

如果有一個json庫能支持上面的四點,那就基本是比較好用的庫了。下面我們來嘗試實現一下這個類庫。

對于我們想要實現的幾個需求,我們可以建立下面這樣的測試來表達我們所期望的庫的API設計:

class A(JsonSerializable):def __init__(self, a, b):super().__init__()self.a = aself.b = b if b is not None else B(0)@propertydef id(self):return self.adef _deserialize_prop(self, name, deserialized):if name == ’b’:self.b = B.deserialize(deserialized)returnsuper()._deserialize_prop(name, deserialized)class B(JsonSerializable):def __init__(self, b):super().__init__()self.b = bclass JsonSerializableTest(unittest.TestCase):def test_model_should_serialize_correctly(self):self.assertEqual(json.dumps({’a’: 1, ’b’: {’b’: 2}}), A(1, B(2)).serialize())def test_model_should_deserialize_correctly(self):a = A.deserialize(json.dumps({’a’: 1, ’b’: {’b’: 2}}))self.assertEqual(1, a.a)self.assertEqual(2, a.b.b)def test_model_should_deserialize_with_default_value_correctly(self):a = A.deserialize(json.dumps({’a’: 1}))self.assertEqual(1, a.a)self.assertEqual(0, a.b.b)

這里我們希望通過繼承的方式來添加支持,這將在反序列化的時候提供一個好處。因為有了它我們就可以直接使用A.deserialize方法來反序列化,而不需要提供任何其他的反序列化函數參數,比如這樣json.deserialize(serialized_str, A)。

同時為了驗證我們的框架不會將@property屬性序列化或者反序列化,我們特意在類A中添加了這樣一個屬性。

由于在反序列化的時候,框架是無法知道某一個對象屬性的類型信息,比如測試中的A.b,為了能正確的反序列化,我們需要提供一點簡單的支持,這里我們在類A中覆蓋實現了一個父類的方法_deserialize_prop對屬性b的反序列化提供支持。

當我們要反序列化一個之前版本的序列化結果時,我們希望能正確的反序列化并使用我們提供的默認值作為最終的反序列化值。這在屬性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,序列化反序列化將不能正常工作

雖然有上述限制,但是這正好要求我們在做模型設計的時候保持克制,不要將某一個對象設計得過于復雜。比如如果有屬性為dict類型,我們可以將這個dict抽象為另一個自定義類型,然后用類型嵌套的方式來實現。

到這里這個基類就差不多可以支撐我們日常的開發需要了。當然對于這個簡單的實現還有可能有其他的需求或者問題,大家如有發現,歡迎留言交流。

總結

到此這篇關于利用Python實現Json序列化庫的文章就介紹到這了,更多相關Python實現Json序列化庫內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 齿轮减速电机一体机_蜗轮蜗杆减速马达-德国BOSERL齿轮减速机带电机生产厂家 | 洛阳永磁工业大吊扇研发生产-工厂通风降温解决方案提供商-中实洛阳环境科技有限公司 | 裹包机|裹膜机|缠膜机|绕膜机-上海晏陵智能设备有限公司 | 电竞学校_电子竞技培训学校学院-梦竞未来电竞学校官网 | 搜木网 - 木业全产业链交易平台,免费搜货、低价买货! | 长沙中央空调维修,中央空调清洗维保,空气能热水工程,价格,公司就找维小保-湖南维小保环保科技有限公司 | 焊锡丝|焊锡条|无铅锡条|无铅锡丝|无铅焊锡线|低温锡膏-深圳市川崎锡业科技有限公司 | 硅PU球场、篮球场地面施工「水性、环保、弹性」硅PU材料生产厂家-广东中星体育公司 | 湖南长沙商标注册专利申请,长沙公司注册代理记账首选美创! | 手板-手板模型-手板厂-手板加工-生产厂家,[东莞创域模型] | 合肥地磅_合肥数控切割机_安徽地磅厂家_合肥世佳电工设备有限公司 | LED显示屏_LED屏方案设计精准报价专业安装丨四川诺显科技 | 超声波反应釜【百科】-以马内利仪器 | 恒压供水控制柜|无负压|一体化泵站控制柜|PLC远程调试|MCGS触摸屏|自动控制方案-联致自控设备 | 灌装封尾机_胶水灌装机_软管灌装封尾机_无锡和博自动化机械制造有限公司 | 硬质合金模具_硬质合金非标定制_硬面加工「生产厂家」-西迪技术股份有限公司 | 考勤系统_考勤管理系统_网络考勤软件_政企|集团|工厂复杂考勤工时统计排班管理系统_天时考勤 | 建筑资质代办-建筑企业资质代办机构-建筑资质代办公司 | 【甲方装饰】合肥工装公司-合肥装修设计公司,专业从事安徽办公室、店面、售楼部、餐饮店、厂房装修设计服务 | 注塑机-压铸机-塑料注塑机-卧式注塑机-高速注塑机-单缸注塑机厂家-广东联升精密智能装备科技有限公司 | 钢制拖链生产厂家-全封闭钢制拖链-能源钢铝拖链-工程塑料拖链-河北汉洋机械制造有限公司 | 温泉机设备|温泉小镇规划设计|碳酸泉设备 - 大连连邦温泉科技 | 原子吸收设备-国产分光光度计-光谱分光光度计-上海光谱仪器有限公司 | TMT观察网_独特视角观察TMT行业| EDLC超级法拉电容器_LIC锂离子超级电容_超级电容模组_软包单体电容电池_轴向薄膜电力电容器_深圳佳名兴电容有限公司_JMX专注中高端品牌电容生产厂家 | 土壤水分自动监测站-SM150便携式土壤水分仪-铭奥仪器 | 软文发布平台 - 云软媒网络软文直编发布营销推广平台 | bng防爆挠性连接管-定做金属防爆挠性管-依客思防爆科技 | 泥沙分离_泥沙分离设备_泥砂分离机_洛阳隆中重工机械有限公司 | 选矿设备-新型重选设备-金属矿尾矿重选-青州冠诚重工机械有限公司 | 衡阳耐适防护科技有限公司——威仕盾焊接防护用品官网/焊工手套/焊接防护服/皮革防护手套 | 火锅加盟_四川成都火锅店加盟_中国火锅连锁品牌十强_朝天门火锅【官网】 | 旋片真空泵_真空泵_水环真空泵_真空机组-深圳恒才机电设备有限公司 | 百度爱采购运营研究社社群-店铺托管-爱采购代运营-良言多米网络公司 | 石英陶瓷,石英坩埚,二氧化硅陶瓷-淄博百特高新材料有限公司 | 橡胶接头|可曲挠橡胶接头|橡胶软接头安装使用教程-上海松夏官方网站 | 政府园区专业委托招商平台_助力企业选址项目快速落地_东方龙商务集团 | 定量包装秤,吨袋包装称,伸缩溜管,全自动包装秤,码垛机器人,无锡市邦尧机械工程有限公司 | 排烟防火阀-消防排烟风机-正压送风口-厂家-价格-哪家好-德州鑫港旺通风设备有限公司 | 置顶式搅拌器-优莱博化学防爆冰箱-磁驱搅拌器-天津市布鲁克科技有限公司 | 许昌奥仕达自动化设备有限公司 |