修改python jsonpickle源码, 实现不序列化对象私有成员

news/2024/12/18 22:23:51/文章来源:https://www.cnblogs.com/huzhongqiang/p/18615729

问题及解决方案

jsonpickle是比较常用的序列化模块, 其特点是对于复杂的对象基本上都能够很好的序列化, 适用范围比较广.
有时候我们有需求, 希望私有变量能够不被序列化, 但是使用jsonpickle的自定义定制机制实现起来不太方便, 可以采用如下的方式:

class NoSerailPrivates:'''表示不序列化私有变量, 以_开头都变量'''def __getstate__(self):'''对于jsonpickle模块, 决定序列化哪些属性, 以'_'开头的属性不序列化'''state = self.__dict__.copy()# 创建一个临时副本进行迭代和删除操作temp_dict = state.copy()for key in temp_dict.keys():if key.startswith('_'): del state[key]return statedef __setstate__(self, state):# 在这里执行初始化操作#self.__init__()    # 可以调用初始化函数, 初始化那些没有序列化的属性self.__dict__.update(state)

但是这种方式, 需要被序列化对象继承NoSerailPrivates或者在内部实现__getstate__, __setstate__, 另外, 如果对象包含子对象, 子对象也要做同样的事情.
当然, 还有别的办法, 比如注册自定义处理器, 但是也需要与被序列化类绑定, 并且对于子对象也需要绑定.
那么有没有办法可以对所有对象默认具有忽略私有成员的功能呢? 我目前还没有找到解决方案. 只能尝试修改源码了, 好在并不是很难.
下面讲一下主要修改步骤:

  1. 修改pickler.py文件中def _flatten_obj_instance(self, obj):函数. 这个函数负责把一个对象转换为序列化后的字符串.
    修改点: 增加一个exclude_privates=True参数选项, 这个选项是原本没有的, 是我新添加的. 用于后面是否过滤掉私有成员时判断.
return self._flatten_dict_obj(obj.__dict__, data, exclude=exclude, exclude_privates=True)
  1. 修改pickler.py文件中def _flatten_dict_obj(self, obj, data=None, exclude=(), exclude_privates=False):函数. 这个函数负责把(k,v)字典转换为序列化后的字符串.
    修改点:
    2.1 函数增加一个exclude_privates=False参数选项;
    2.2 在下面的代码中增加一个exclude_privates=exclude_privates参数选项, 这个选项的值继承自此函数的传入参数.
for k, v in util.items(obj, exclude=exclude, exclude_privates=exclude_privates):
  1. 修改util.py文件的def items(obj, exclude=(), exclude_privates=False):函数. 这个函数负责枚举字典的key,value并进行过滤.
    修改点:
    3.1 函数增加一个exclude_privates=False参数选项;
    3.2 函数实现代码修改如下, 提供对象私有成员过滤功能:
def items(obj, exclude=(), exclude_privates=False):"""TODO: Replace all calls to this with plain dict.items()"""for k, v in obj.items():if k in exclude:continueif exclude_privates:if isinstance(k,str) and k.startswith('_'):continueyield k, v

最后实现效果

测试代码如下:

import jsonpickleclass InnerClass:def __init__(self):self.public_var = 'hzqtest'self.__private_var = 20class OuterClass:def __init__(self):self.public_var = 100self.__private_var = 200self.inner = InnerClass()  # 嵌套对象obj = OuterClass()
#obj = {'hzqtest':10,'_abc':100}
json_str = jsonpickle.encode(obj)
print(json_str)  # 输出应仅包含 public_var

输出信息: {"py/object": "__main__.OuterClass", "public_var": 100, "inner": {"py/object": "__main__.InnerClass", "public_var": "hzqtest"}}
由此可见, 对象私有成员被屏蔽.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/855052.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【建议收藏】最新版IDEA2024.3及 AI Assistant 一键激活到2099

成功永久激活 一、支持的IDE和版本支持JB家族所有IDE激活 支持版本为2021.3~2024.1二、如何破解激活 第一步:激活工具下载 为了防止破解工具被删除,通过公众号回复“「永久激活」”获取下载最新工具(如过期,请记得提醒我哦) 关注公众号后台回复“「永久激活」”,获取最新…

《平衡树》读后感

第一框,世界属于fhq-treap 是什么? 你说的对,但是《fhq-treap》是由范浩强自主研发的一款全新树形数据结构。数据结构发生在一个被称作「二叉搜索树」的幻想世界,在这里,被人创造的节点将被授予「随机优先级」,导引期望 \(O(\log n)\) 之力。treap 将扮演一位名为「根据优…

虚拟机unraid系统安装

首先下载unraid文件https://unraid.net/getting-started windows系统使用vmware虚拟机 创建虚拟机过程中注意usb的不同协议 2.0 3.0 由于unraid系统只能识别fat32协议的文件系统,因此需要将u盘格式化 可以使用easeus 或者 傲梅 https://www.easeus.com/partition-manager/ htt…

基于.NET WinForm开发的一款硬件及协议通讯工具

前言 今天大姚给大家分享一款基于.NET WinForm开发的一款硬件及协议通讯工具:PLC-CommunTools。 项目介绍 PLC-CommunTools是一款基于.NET WinForm开发的一款硬件及协议通讯工具,包含各类厂商的PLC协议及基础的TCP、串口通讯、IO口通讯等协议通讯功能的实现整合,注意还有一部…

游戏过程

根据是否结束游戏的逻辑选择对掷骰子的过程用bool申明变量掷骰子 static bool RollDice (w,h,ref Player p1,ref Player p2,Map map) {InfoClear(h);Console.ForegroundColor=p1.type==E_PlayerType.Player?ConsoleColor.Cyan:ConsoleColor.Meganta;if(p1.isPause){p1.isPause…

6.Group组件

关于Group组件的简单介绍首先,Group组件本身并不是一个“布局”类的组件,它只是一个容器,没有提供调整内部组件展示位置的方法,也就是说,当我们将多个组件(比如button)放在group中时,他们(根据流式规则?)会全部挤在窗口的左上角,当然,如果我们没有设置组件的大小的话…

直播预告:OpenAI 开始拥抱 RTC!为什么 LLM+RTC 才是多模态 AI 的未来?丨RTE Dev Talk

如果您正在开发具备语音对话、视觉理解等多模态能力的 AI Agent,请加入我们的直播讨论!OpenAI 今日发布了 OpenAI Realtime API 的重大更新,其中包括价格下调、新增模型以及一项尤为重要的改进: WebRTC 支持 。结合此前 WebRTC 创建者加入 OpenAI 的消息,这清晰地表明 Ope…

实验6 模板类、文件I/O与异常处理

实验四 vector.hpp#pragma once#include<iostream>#include<stdexcept>using namespace std;template<typename T>class Vector {private:int size;T* ptr;public:Vector(int size, int value = 0) :size{ size } {if (size < 0) {throw length_error(&qu…

把半年前完全没思路的题解了的感觉真好

虽然处理了很多次索引思路,不过最后还是过了。第一眼就有解题思路,这种感觉真不错,要的就是这种打怪升级的正反馈。 附上解题代码 `# @lc app=leetcode.cn id=2266 lang=python3[2266] 统计打字方案数@lc code=start from collections import Counter from functools import…

【Windows安全】13种回调函数执行ShellCode

#windows #回调函数 回调机制 在我们使用回调函数执行Shellcode之前,我们首先需要去了解Windows回调机制,Windows回调机制就像你和你的助手一样,比如说每一个律师所中的每一个律师都有一个实习助手,律师需要助手在特定的情况下去处理一些特殊的任务,但这些任务并不是日常…

MaLoader:一款基于Tauri+Rust的免杀马生成工具

免责声明 本公众号“黑客之道HackerWay”提供的资源仅供学习,利⽤本公众号“黑客之道HackerWay”所提供的信息而造成的任何直接或者间接的后果及损失,均由使⽤者本⼈负责,本公众号“黑客之道HackerWay”及作者不为此承担任何责任,一旦造成后果请自行承担责任!简介 MaLoade…

Element Plus组件库el-select组件多选回显踩坑

前情公司有经常需要做一些后台管理页面,我们选择了Element Plus,它是基于 Vue 3,面向设计师和开发者的组件库,是Vue框架生态中比较火的UI组件库,组件库丰富易用,组件链接:一个 Vue 3 UI 框架 | Element Plus,项目中经常会用到el-select多选功能,组件自带的多选交互也是…