玩转序列化,用这个库就对了:Python的pickle库
文章目录
玩转序列化,用这个库就对了:Python的pickle库
背景
在Python编程中,我们经常需要将对象转换成字节流以便存储或传输。这个过程被称为序列化。序列化是将数据结构或对象状态转换成可存储或可传输的形式的过程。而反序列化则是相反的过程,即将字节流转换回原始的数据结构或对象。Python标准库中的pickle
库正是为此而生,它提供了一种简单而高效的方式来序列化和反序列化Python对象结构。
什么是pickle库?
pickle
是Python的一个内置库,用于序列化和反序列化Python对象结构。它能够将Python对象转换成一个字节流,以便可以将其存储在文件中或通过网络传输,之后又可以将这些字节流重新转换成原来的Python对象。
如何安装这个库?
由于pickle
是Python的标准库,因此无需额外安装。只需在Python脚本中导入即可使用:
import pickle
5个简单的库函数使用方法
dump函数
将Python对象序列化并写入文件。
import pickle
data = {'key': 'value'}
with open('data.pkl', 'wb') as f:
pickle.dump(data, f)
import pickle
:导入pickle库。data = {'key': 'value'}
:创建一个字典对象。with open('data.pkl', 'wb') as f
:以二进制写入模式打开文件。pickle.dump(data, f)
:将data对象序列化并写入文件。load函数
从文件中反序列化Python对象。
import pickle
with open('data.pkl', 'rb') as f:
data = pickle.load(f)
print(data)
with open('data.pkl', 'rb') as f
:以二进制读取模式打开文件。data = pickle.load(f)
:从文件中读取字节流并反序列化成Python对象。dumps函数
将Python对象序列化成字节流。
import pickle
data = {'key': 'value'}
serialized_data = pickle.dumps(data)
print(serialized_data)
serialized_data = pickle.dumps(data)
:将data对象序列化成字节流。loads函数
从字节流中反序列化Python对象。
import pickle
serialized_data = b'\x80\x03}q\x00(X\x03\x00\x00\x00keyq\x01X\x05\x00\x00\x00valueq\x02e.'
data = pickle.loads(serialized_data)
print(data)
data = pickle.loads(serialized_data)
:从字节流中反序列化成Python对象。高级用法:使用协议
pickle
支持不同的序列化协议,可以通过protocol
参数指定。
import pickle
data = {'key': 'value'}
with open('data.pkl', 'wb') as f:
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
:使用最高版本的协议序列化对象。5个场景使用代码说明
场景1:保存和加载自定义类实例
import pickle
class MyClass:
def __init__(self, name):
self.name = name
# 创建实例
my_object = MyClass("Kimi")
# 序列化
with open('my_object.pkl', 'wb') as f:
pickle.dump(my_object, f)
# 反序列化
with open('my_object.pkl', 'rb') as f:
loaded_object = pickle.load(f)
print(loaded_object.name)
场景2:保存和加载复杂数据结构
import pickle
data = {'list': [1, 2, 3], 'dict': {'a': 1, 'b': 2}, 'tuple': (1, 2)}
# 序列化
with open('complex_data.pkl', 'wb') as f:
pickle.dump(data, f)
# 反序列化
with open('complex_data.pkl', 'rb') as f:
loaded_data = pickle.load(f)
print(loaded_data)
场景3:跨网络传输Python对象
import pickle
import socket
# 创建一个socket对象
s = socket.socket()
s.connect(('example.com', 12345))
# 序列化对象
data = {'key': 'value'}
serialized_data = pickle.dumps(data)
# 发送数据
s.sendall(serialized_data)
# 关闭连接
s.close()
场景4:多进程中使用pickle
import pickle
from multiprocessing import Process, Pipe
def worker(conn):
conn.send(pickle.loads(conn.recv()))
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=worker, args=(child_conn,))
p.start()
parent_conn.send(pickle.dumps({'key': 'value'}))
print(parent_conn.recv())
p.join()
场景5:使用pickle进行深拷贝
import pickle
data = {'key': 'value'}
# 深拷贝
copied_data = pickle.loads(pickle.dumps(data))
print(copied_data is data) # False,证明是深拷贝
常见3个bug以及解决方案
Bug1:尝试序列化不支持的对象
错误信息:TypeError: Can't pickle <type>: <attribute>
解决方案:
确保所有要序列化的对象都是pickle
支持的类型。如果需要序列化自定义对象,确保它们是可序列化的。
import pickle
class MyClass:
def __init__(self, name):
self.name = name
# 正确的序列化方式
my_object = MyClass("Kimi")
with open('my_object.pkl', 'wb') as f:
pickle.dump(my_object, f)
Bug2:使用旧版本的pickle库打开新版本序列化的数据
错误信息:pickle.UnpicklingError: invalid load key, bytes le
解决方案:
确保使用相同版本的pickle
库进行序列化和反序列化。
import pickle
# 序列化
data = {'key': 'value'}
with open('data.pkl', 'wb') as f:
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
# 反序列化
with open('data.pkl', 'rb') as f:
data = pickle.load(f)
Bug3:在不同Python版本间序列化和反序列化
错误信息:pickle.UnpicklingError: bad byte load key
解决方案:
在不同Python版本间序列化和反序列化时,使用兼容的协议版本。
import pickle
# 序列化
data = {'key': 'value'}
with open('data.pkl', 'wb') as f:
pickle.dump(data, f, protocol=pickle.DEFAULT_PROTOCOL)
# 反序列化
with open('data.pkl', 'rb') as f:
data = pickle.load(f)
总结
pickle
库是Python中一个强大而灵活的序列化工具,它能够处理各种复杂的数据结构,并且易于使用。通过本文的介绍,你应该能够掌握pickle
的基本用法,以及如何在实际场景中应用它。记住,虽然pickle
非常方便,但由于其安全性问题,不建议用于序列化不可信的数据。对于需要高安全性的场景,可以考虑使用其他序列化库,如json
或xml
。
如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!
作者:正东AI