Python 如何让一个类支持 pickle 但排除某些敏感属性

8次阅读

可通过自定义__getstate__方法控制pickle序列化时包含的属性,移除password、_cache等敏感或临时字段,避免其被持久化。

Python 如何让一个类支持 pickle 但排除某些敏感属性

可以通过自定义 __getstate__ 方法控制 pickle 序列化时包含哪些属性,把不想保存的敏感字段(如密码、临时连接、回调函数等)从状态字典中移除。

使用 __getstate__ 过滤敏感属性

对象被 pickle 时,python 会优先调用 __getstate__ 获取要序列化的状态字典。你可以在该方法中返回一个不包含敏感字段的新字典。

  • 在方法内复制 self.__dict__,再 del 掉敏感键
  • 推荐用 .pop() 或字典推导式过滤,避免修改原对象状态
  • 不需要重写 __setstate__,除非你对反序列化逻辑有特殊要求

示例:排除 password 和 _cache 属性

(假设类中存在敏感字段 password 和内部缓存 _cache

import pickle 

class User: def init(self, name, password, email): self.name = name self.password = password # 敏感字段 self.email = email self._cache = {} # 不应持久化的临时数据

def __getstate__(self):     # 创建当前状态的副本     state = self.__dict__.copy()     # 移除敏感和临时字段     state.pop('password', None)     state.pop('_cache', None)     return state

使用

u = User("Alice", "s3cr3t!", "alice@example.com") data = pickle.dumps(u) # password 和 _cache 不会出现在 data 中 u2 = pickle.loads(data) # u2.password 不存在,u2._cache 也不会被恢复

补充说明:其他注意事项

  • 如果类中有不可 pickle 的属性(如文件句柄、线程锁、Lambda 函数),也必须在 __getstate__ 中排除,否则会报 PicklingError
  • 若需在反序列化后重建某些资源(如重新初始化 _cache),可实现 __setstate__,并在其中添加逻辑
  • 继承自内置类型或使用 __slots__ 的类需额外注意:此时 __dict__ 可能不存在,应改用 vars(self) 或显式构造状态字典

text=ZqhQzanResources