当前位置: 首页 > 图灵资讯 > 行业资讯> 一文了解Python序列化

一文了解Python序列化

发布时间:2025-04-06 15:42:05

当程序运行时,所有变量都存储在内存中。当程序结束时,这些占用的内存将被系统回收,无法长期存储。将这些变量转换为可存储或通过网络传输的过程称为序列化(pickling),它们可以存储在磁盘中或通过网络传输。

1.pickle序列化

Python为实现变量的序列化提供了pickle模块,该模块可以将变量转换为字节码(bytes)形式存储还可以将存储的序列化字节码恢复到数据对象中;

注:pickle只能用于python程序之间的数据交换,不同版本之间不兼容。当需要与其他程序通信时,请使用json序列化,它可以在不同的编程语言之间共享数据。

a.pickle普通对象序列化

先看一个小例子,用pickle模块序列化几个不同的对象,可以用于网络传输或存储到磁盘文件中:

#!/usr/bin/envpython3
#coding=utf-8
importos
importpickle
#创建字典对象和字符串对象
d=dict(one=1,two=2,three=3)
s="python"
print(d)#输出{'three':3,'two':2,'one':1}
print(s)#输出

#将这两个对象序列化,nd和ns仅保存在内存中,可用于网络传输
nd=pickle.dumps(d)
ns=pickle.dumps(s)
print(nd)#输出字节码"b'\x80\x03}q\x00..."
print(ns)#输出字节码"b'x80\x03xxx11..."

#将序列化后的对象恢复到数据(假设接收端接收到这些数据,可以这样还原)
nd=pickle.loads(nd)
ns=pickle.loads(ns)
print(nd)#输出{'three':3,'two':2,'one':1}
print(ns)#输出

#创建文件testfile,接收字节码(wb),在d对象中写入数据,
#用于本地不同应用程序之间的数据交换(此时,如果我们打开testfile文件,
#可以看到一些类似乱码的字符,实际上是d对象序列化后的数据)
withopen("testfile","wb")asf1:
pickle.dump(d,f1)

#从testfile文件中读取字节码,恢复数据
ifos.path.isfile("testfile"):
withopen("testfile","rb")asf2:
print(f2.read()#输出"b'\x80\x03}q\x0..."
#由于上一步读取了数据,指针位置应重新设置为起始位置,
#这只是为了向你展示,上面的print和seek可以不写
f2.seek(0)
d=pickle.load(f2)#读取f2中的数据恢复
print(d)#输出{'three':3,'two':2,'one':1}

结论:仅在内存中序列化和还原,使用dumps()和loads(),将数据序列化后保存到文件中使用dump(),从文件中还原数据使用load(),两者只有一个s的区别,注意不要混淆。

b.pickle类序列化

有时我们可能需要传输或保存一个类对象和所有数据。python中的实现类序列化非常简单,与对象序列化没有区别。请参见以下示例:

#!/usr/bin/envpython3
#coding=utf-8
importpickle
########
classA:
#--------
def__init__(self,name="py",website="python"):
self.name=name
self.website=website
x=A()
x.name="晴刃"

#序列化实例x,可用于网络传输
nx=pickle.dumps(x)
print(nx)#输出"b'________________________main__..."

#还原数据
nx=pickle.loads(nx)
print(nx)#输出"<__main__.Aobjectat0x7f43c95c08>"

#将类对象序列化并保存到磁盘文件中,可用于程序间数据交换
withopen("testfile","wb")asf1:
pickle.dump(x,f1)

#读取文件中的数据恢复
withopen("testfile","rb")asf1:
y=pickle.load(f1)
print(y.name)#输出"晴刃"
print(y.website)#输出

2.json序列化

如果要在不同的编程语言之间传输对象,可以使用pythonjson模块对数据进行序列化。json序列化后,所有数据都表示为字符串形式,可以通过所有语言读取,也可以轻松存储到磁盘或通过网络传输,但在类数据转换中会有点麻烦,不像pickle那么方便。

a.Json普通对象序列化

#!/usr/bin/envpython3
#coding=utf-8
importjson

#创建字典对象和浮点数对象
d=dict(one=1,two=2,three=3)
f=3.14

print(type(d))#<class'dict'>
print(type(f))#<class'float'>

#普通对象的序列化与pickle相同
nd=json.dumps(d)
nf=json.dumps(f)

#转换后,所有对象都变成了字符串类型<class'str'>
print(type(nd))
print(type(nf))
print(nd)#"{"three":3,"two":2,"one":1}"
print(nf)#"3.14"

#还原数据
nd=json.loads(nd)
nf=json.loads(nf)
print(type(nd))#<class'dict'>
print(type(nf))#<class'float'>

#将d对象序列化并存储在testfile文件中
withopen("testfile","w")asf1:
json.dump(d,f1)

#从testfile文件中读取数据并恢复数据
withopen("testfile","r")asf1:
y=json.load(f1)
print(type(y))#<class'dict'>

b.json类序列化

使用json序列化类会有点复杂,因为json的dump方法不知道如何将一个类转换为字符串,所以我们需要指定一个转换函数。请参见以下例子:

#!/usr/bin/envpython3
#coding=utf-8
importjson

classA(object):
def__init__(self,name="py",website="python"):
self.name=name
self.website=website
#一个类实例的初始化
a=A()

#创建函数,以字典的形式返回类A中的对象和数据
defclasassa2dict(c):
return{"name":c.name,"website":c.website}

#使用json序列化a,参数default告诉python解释器,将前对象a传输到后clasa2dict函数处理,
#clasa2dict函数将返回包含实例a中所有对象和数据的字典类型"键值对",
#然后dumps函数将返回的字典类型序列为字符串类型
x=json.dumps(a,default=classa2dict)
#如果想偷懒不写classa2dict函数,有一种简便方法,使用匿名函数,并且调用基类的__dict__函数,
#这个函数会完成和classa2dict函数相同的功能,即将一个类的所有属性转换成字典"键值对"的形式
#x=json.dumps(a,default=lambdaobj:obj.__dict__)

print(type(x))#<class'str'>
print(x)#"{"website":"python","name":"py"}"

#字典类型转换为类型返回
defdict2classA(d):
returnA(d["name"],d["website"])

#将json序列后的数据还原为类,object_hook参数将x转换为字典类型,并将x转换为dict2clasa函数处理,
#dict2classa函数将读取字典中的每个键,并将值传输到a类进行初始化,并返回一个类对象
x=json.loads(x,object_hook=dict2classA)
print(type(x))#<class'__main__.A'>
print(x.website)

#将序列化类写入文件testfile中
withopen("testfile","w")asf1:
json.dump(a,f1,default=classa2dict)
#读取testfile中的数据恢复
withopen("testfile","r")asf2:
y=json.load(f2,object_hook=dict2classA)
print(y.name)

python培训视频众多,全部在python学习网,欢迎在线学习!

本文转自:https://www.jianshu.com/p/f4cfa19abca4

相关文章

如何让vim支持python3

如何让vim支持python3

2025-09-12
python2.7和3.6区别有哪些

python2.7和3.6区别有哪些

2025-09-12
python3有serial库吗

python3有serial库吗

2025-09-12
python中w、r表示什么意思

python中w、r表示什么意思

2025-09-12
python中如何把list变成字符串

python中如何把list变成字符串

2025-09-12
python命名空间是什么

python命名空间是什么

2025-09-12