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

在前一篇文章中, 通过修改源码来实现对象的私有成员不被序列化的功能. 但是不够灵活, 于是我又修改了一版, 能够自定义过滤函数.
实现起来不是很难, 要点如下:

# pickler.py的_flatten_obj_instance函数
self._current_obj = obj  # 记录正在处理的对象
return self._flatten_dict_obj(obj.__dict__, data, exclude=exclude)
# pickler.py的_flatten_dict_obj函数
# 过滤函数进行包装
filter_func = lambda k, v: self.filter_func(self._current_obj, k, v) if self.filter_func else None
# If we have string keys only then we only need a single pass.
flatten = self._flatten_key_value_pair
for k, v in util.items(obj, exclude=exclude,filter=filter_func):
    flatten(k, v, data)
# pickler.py的encode函数
# 增加一个过滤函数
filter_func = None  # 过滤函数, 用于过滤掉不需要序列化的属性. 形式: filter_func(obj, key, value)

运行效果

import jsonpickle

class InnerClass:
    def __init__(self):
        self.public_var = 'hzqtest'
        self.__private_var = 20

class OuterClass:
    def __init__(self):
        self.public_var = 100
        self.__private_var = 200
        self.inner = InnerClass()  # 嵌套对象

def test(obj,k,v):
    print(obj.__class__.__name__,k,v)
    return not (isinstance(k,str) and k.startswith('_'))

obj = OuterClass()
#obj = {'hzqtest':10,'_abc':100}
json_str = jsonpickle.encode(obj,filter_func=test)
print(json_str)  # 输出应仅包含 public_var

输出:

OuterClass public_var 100
OuterClass _OuterClass__private_var 200
OuterClass inner <__main__.InnerClass object at 0x000002C380155C40>
InnerClass public_var hzqtest
InnerClass _InnerClass__private_var 20
{"py/object": "__main__.OuterClass", "public_var": 100, "inner": {"py/object": "__main__.InnerClass", "public_var": "hzqtest"}}
posted @ 2024-12-19 18:29  顺其自然,道法自然  阅读(6)  评论(0编辑  收藏  举报