泸州本地网站建设,如何快速制作网页界面,一级a做爰片免费网站体验,免费可以做旅游海报 的网站一、pickle 是什么#xff1f;
pickle 是 Python 标准库中的对象序列化工具#xff1a;
序列化#xff08;dumping / pickling#xff09;#xff1a;把内存中的 Python 对象#xff08;如列表、字典、自定义类实例等#xff09;转换成字节流#xff08;bytes#xff…一、pickle 是什么pickle是 Python 标准库中的对象序列化工具序列化dumping / pickling把内存中的 Python 对象如列表、字典、自定义类实例等转换成字节流bytes以便写入文件通过网络发送存入缓存或数据库的二进制字段等反序列化loading / unpickling把字节流重新还原为原先的 Python 对象。特点支持大多数内置类型和自定义类实例。是 Python 专用的二进制协议不同语言之间不通用。默认协议不是可读文本不是 JSON / YAML而是二进制格式。适用场景在 Python 环境内部保存/恢复复杂对象如机器学习模型、缓存的中间结果、复杂数据结构等。二、基本接口与常用函数1. 常用函数importpickle# 写入/读取文件接口pickle.dump(obj,file,protocolNone)# 序列化到文件对象pickle.load(file)# 从文件对象反序列化# 操作 bytes 接口pickle.dumps(obj,protocolNone)# 序列化为 bytespickle.loads(data)# 从 bytes 反序列化protocol序列化协议版本整数一般用protocolpickle.HIGHEST_PROTOCOL推荐不写时使用默认协议不同 Python 版本默认值不同三、基础用法示例1. 序列化到文件 / 从文件加载importpickle data{name:Alice,age:25,scores:[95,88,76],active:True}# 写入文件推荐使用二进制模式 wbwithopen(data.pkl,wb)asf:pickle.dump(data,f,protocolpickle.HIGHEST_PROTOCOL)# 从文件读取withopen(data.pkl,rb)asf:loaded_datapickle.load(f)print(loaded_data)说明文件扩展名通常用.pkl、.pickle或.p仅是约定非强制。必须使用二进制模式wb/rb。2. 转换为 bytes / 从 bytes 恢复importpickle obj[1,2,3,{a:10}]data_bytespickle.dumps(obj,protocolpickle.HIGHEST_PROTOCOL)# 可以用于网络传输、缓存等restoredpickle.loads(data_bytes)print(restored)四、pickle 支持哪些类型大多数常见类型都支持基本类型int、float、bool、str、bytes、None容器类型list、tuple、dict、set、frozenset函数、类、实例有一些限制见后文datetime、decimal.Decimal、fractions.Fraction等常用内置类型许多第三方库对象如大部分sklearn模型——库作者实现了对应的序列化协议不太适合 / 有限制的对象打开的文件对象、数据库连接、线程、进程、锁等与系统资源强绑定的对象常常无法完全恢复原状态反序列化时环境已不同lambda 匿名函数、内部函数、局部类等普通pickle不能可靠处理要用dill等扩展库五、pickle 协议protocol版本protocol是决定如何编码对象为字节流的“格式版本”。常用写法pickle.dump(obj,f,protocolpickle.HIGHEST_PROTOCOL)查看当前解释器支持的最高协议importpickleprint(pickle.HIGHEST_PROTOCOL)越新的协议通常更高效、更紧凑但在旧版本 Python 上可能无法反序列化跨 Python 版本使用 Pickle 时如果你需要在不同 Python 版本间共享.pkl文件建议在较低版本的 Python 中查看HIGHEST_PROTOCOL然后在较高版本中固定使用该协议版本。或者使用更兼容的格式如 JSON、msgpack 等。六、自定义类的 pickle 行为1. 直接序列化自定义类实例默认情况下自定义类的实例是可以被 pickle 的importpickleclassPerson:def__init__(self,name,age):self.namename self.ageage pPerson(Alice,25)# 序列化datapickle.dumps(p)# 反序列化p2pickle.loads(data)print(p2.name,p2.age)要求类定义在模块的顶层作用域不是函数内部。反序列化时需要能找到同名模块和类定义否则会失败也就是说Person类定义在mymodule.py中那么加载 pickle 时环境里也要有mymodule.Person。2. 控制属性__getstate__与__setstate__如果你想某些属性不参与序列化如打开的文件句柄序列化前/后做一些处理可以在类中实现classPerson:def__init__(self,name,age,temp_fileNone):self.namename self.ageage self.temp_filetemp_file# 不打算序列化这个属性def__getstate__(self):# 返回要被序列化的“状态”字典stateself.__dict__.copy()# 删除不希望被序列化的属性iftemp_fileinstate:delstate[temp_file]returnstatedef__setstate__(self,state):# 从状态恢复实例self.__dict__.update(state)# 反序列化后可赋默认值或重新构造资源self.temp_fileNone说明__getstate__返回任何可被 pickle 序列化的对象通常是 dict。__setstate__(state)用来根据序列化得到的state恢复对象内部状态。3. 更底层的控制__reduce__/__reduce_ex__当序列化某个对象时pickle会调用obj.__reduce_ex__(protocol)如存在否则调用obj.__reduce__()它们需要返回一种描述如何重新构造该对象的信息一般形式是一个 25 元组常见形式(callable,args,state)示例简单展示用法不必死记classMyClass:def__init__(self,value):self.valuevalue self.cachevalue*2# 想在恢复时重新计算def__reduce__(self):# 用 MyClass 构造函数和一个参数创建实例reconstruct_callableself.__class__ reconstruct_args(self.value,)# state 用于存其他信息这里暂时用 NonestateNonereturn(reconstruct_callable,reconstruct_args,state)def__setstate__(self,state):# 反序列化后重新构造 cacheself.cacheself.value*2平时多数情况下只用__getstate__/__setstate__即可__reduce__适合高级定制或 C 扩展类。七、处理大型对象与性能优化1. 使用最高协议 二进制 I/Opickle.dump(obj,f,protocolpickle.HIGHEST_PROTOCOL)优点通常速度更快文件更小2. 使用protocol 4的大对象支持新协议对大对象4GB支持更好。Python 3.8 中的默认协议已足够。3. 对于多对象序列化若你想把多个对象“顺序写入”同一个文件withopen(multi.pkl,wb)asf:pickle.dump(obj1,f,protocolpickle.HIGHEST_PROTOCOL)pickle.dump(obj2,f,protocolpickle.HIGHEST_PROTOCOL)withopen(multi.pkl,rb)asf:apickle.load(f)bpickle.load(f)注意加载时需要按相同顺序多次调用pickle.load。不可随机访问中间对象除非自己管理偏移量。如果要实现可随机访问的“对象仓库”可考虑shelve模块基于 pickle dbm或自己实现索引对象位置表 seek八、安全性务必注意反序列化风险这是使用 pickle 时最重要的问题。1. pickle 反序列化是不安全的官方文档明确说明对不可信数据调用pickle.load或pickle.loads是危险的可能导致代码执行、系统被攻陷。原因pickle协议中可以编码“调用任意可导入对象”的指令。恶意构造的 pickle 字节流可以在加载时触发执行任意 Python 代码RCE。总结一句话只有在完全信任数据来源的前提下才能使用pickle.load/pickle.loads。2. 安全使用建议绝对不要对以下来源的数据使用pickle.loads用户上传的文件 / 表单网络请求中的数据HTTP body / WebSocket 等来历不明的.pkl文件如果必须支持某种持久化格式给外部使用建议使用 JSON、MessagePack、Protocol Buffers、Avro 等更安全和跨语言的序列化格式。或自行设计清晰受限的数据结构比如只允许 dict/list/str/int 等基本类型。在内部可信环境用 pickle仅在团队内部、受控环境下使用.pkl共享数据。若部署在可能暴露接口的服务中不要直接接受外部传来的 pickled 数据。九、实际例子缓存结果到硬盘示例耗时计算结果缓存到本地下次直接读取。importosimportpickle CACHE_FILEresult_cache.pkldefheavy_compute():# 模拟耗时操作fromtimeimportsleep sleep(3)return{result:42,detail:[1,2,3]}defget_result():ifos.path.exists(CACHE_FILE):withopen(CACHE_FILE,rb)asf:returnpickle.load(f)resheavy_compute()withopen(CACHE_FILE,wb)asf:pickle.dump(res,f,protocolpickle.HIGHEST_PROTOCOL)returnresif__name____main__:print(First call:)print(get_result())print(Second call (should be faster):)print(get_result())十、与其它序列化方式的比较简要方式格式可读性跨语言支持复杂 Python 对象安全默认典型用途pickle二进制否否是否危险Python 内部的对象持久化JSON文本是是限制多基本类型为主相对安全简单配置、Web 接口、跨语言msgpack二进制否是一般相对安全高效跨语言序列化protobuf二进制否是用 schema 定义结构相对安全大规模服务间通信、强类型约束结论只在 Python 内部且数据来源可信用pickle很方便支持自定义类。需要跨语言或不完全可信数据源优先考虑 JSON / msgpack / protobuf 等。十一、小结与使用建议基本用法pickle.dump(obj, f)/pickle.load(f)处理文件pickle.dumps(obj)/pickle.loads(bytes)处理内存中的 bytes。对自定义类顶层定义类反序列化时保持类可导入可以用__getstate__/__setstate__精细控制。性能protocolpickle.HIGHEST_PROTOCOL注意版本兼容问题。安全永远不要反序列化不可信来源的 pickle 数据对外部接口应使用更安全、跨语言的格式。场景典型用途Python 项目内部的模型、缓存、中间结果持久化一次性脚本、实验性数据保存。