修改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"}}