序列化模块:json模块 / pickle模块
【一】概要
json
模块和 pickle
模块都是 Python 中用于序列化和反序列化数据的工具,但它们有一些重要的区别:
可读性和可编辑性:
json
生成的数据是以文本形式表示的,具有良好的可读性,并且可以手动编辑。
pickle
生成的数据是二进制格式的,不具有人类可读性,但可以包含更多种类的 Python 对象。
跨语言支持:
JSON 是一种通用的数据交换格式,支持多种编程语言,不仅限于 Python。
pickle
是 Python 特有的序列化格式,不适用于与其他语言交换数据。
安全性:
JSON 是一种文本格式,通常被认为相对安全,因为它可以通过人类读取和编辑,减少了潜在的安全风险。
pickle
生成的二进制数据包含了执行代码的信息,因此在不受信任的环境中反序列化 pickle
数据可能存在安全风险。
支持的对象类型:
json
可以序列化基本的数据类型(字典、列表、字符串等)以及它们的组合。不支持一些特殊的 Python 对象,如自定义类的实例。
pickle
可以序列化几乎所有 Python 对象,包括自定义类的实例、函数等,但对于某些特殊对象可能存在限制。
使用场景:
json
通常用于 Web 开发中的数据传输、配置文件、API 接口等需要与其他语言交互的场景。
pickle
通常用于本地持久化和 Python 特有的应用场景,例如缓存、保存 Python 对象状态等。
综合考虑这些因素,选择使用 json
还是 pickle
取决于具体的使用场景和需求。如果需要跨语言支持、可读性和编辑性重要,或者在不受信任的环境中使用,推荐使用 json
。如果只在 Python 中使用,并且需要序列化复杂的 Python 对象,可以考虑使用 pickle
。
【二】常见用法
json
json.dump(obj,fp)
将 Python 对象 obj
编码成 JSON 格式的字符串,并将结果写入文件对象 fp
中。
obj
是要编码的对象。
fp
是一个文件对象,用于写入 JSON 数据。
其他参数json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
json.load(fp)
从文件对象 fp
中读取 JSON 格式的数据,解码为 Python 对象。
fp
是一个文件对象,包含了 JSON 数据。
其他参数json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
json.dumps(obj)
将 Python 对象 obj
编码成 JSON 格式的字符串。
obj
是要编码的对象。
参数和 json.dump
中的参数相似,但不需要文件对象。
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
json.loads(s)
从 JSON 格式的字符串 s
中解码出 Python 对象。
s
是包含 JSON 数据的字符串。
参数和 json.load
中的参数相似。
json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
pickle
pickle.dump(obj, file, protocol=None)
其他参数(obj, file, protocol=None, *
, fix_imports
=True, buffer_callback
=None)
将 Python 对象 obj
序列化,并将结果写入文件对象 file
中。
protocol
是协议版本号,可选,默认为最高可用版本。
fix_imports
控制是否尝试导入丢失的模块。
buffer_callback
可用于设置缓冲回调函数(在某些情况下需要)。
pickle.load(file)
其他参数(file, *
, fix_imports
=True, encoding
='ASCII', errors
='strict', buffers
=None)
从文件对象 file
中读取序列化的对象,并返回原始对象。
fix_imports
控制是否尝试导入丢失的模块。
encoding
和 errors
用于指定文本数据的编码和错误处理方式。
buffers
是一个包含缓冲区的可选参数。
pickle常用于json文件无法存储的数据类型,如实例化对象obj等
在PyCharm中,如果file参数传递的值是句柄(使用with语句),可能会报黄,这是因为pickle.dump
和pickle.load
可以直接使用文件名作为参数
但,直接使用pickle.load打开,需要注意使用完文件后关闭文件句柄,以防止资源泄露
所以,可以不用管报黄
【三】详解
【1】什么是序列?
序列(Sequence): 在计算机科学中,序列是一种数据结构,用于存储按顺序排列的一组元素。这些元素可以是字符、数字、对象等。字符串、列表和元组都是 Python 中常见的序列类型。
【2】什么是序列化?
序列化(Serialization): 序列化是将数据结构或对象转换为可以存储或传输的格式的过程。在序列化中,数据被编码成字节流或其他格式,以便在存储到文件、传输到网络或存储在数据库中。序列化的目的是将数据转换为通用格式 ,使其能够在不同系统或环境中传递和重建。
在 Python 中,常见的序列化格式包括 JSON、pickle 等。序列化通常涉及将对象转换为字符串或字节流。
【3】什么是反序列化?
反序列化(Deserialization): 反序列化是序列化的逆过程,即将序列化后的数据重新转换为原始的数据结构或对象。这样可以从文件、网络等位置读取数据,并在程序中使用。反序列化的过程是将字节流或其他格式的数据还原为原始的数据结构。
在 Python 中,反序列化是通过解析 JSON 字符串、使用 pickle 模块等实现的。反序列化过程的目标是从序列化的数据中还原出原始的对象或数据结构。
【4】JSON
(1)JSON文件
[1.1] 查看可以转为json文件的数据类型json.JSONEncoder
Supports the following objects and types by default :
+
| Python | JSON |
+ = = = = = = = = = = = = = = = = = = = + = = = = = = = = = = = = = = = +
| dict | object |
+
| list, tuple | array |
+
| str | string |
+
| int , float | number |
+
| True | true |
+
| False | false |
+
| None | null |
+
[1.2] json文件转为python对象json.JSONDecoder
Performs the following translations in decoding by default :
+
| JSON | Python |
+ = = = = = = = = = = = = = = = + = = = = = = = = = = = = = = = = = = = +
| object | dict |
+
| array | list |
+
| string | str |
+
| number (int ) | int |
+
| number (real ) | float |
+
| true | True |
+
| false | False |
+
| null | None |
+
(2)JSON 文件的基本结构:
对象(Object): 由花括号 {}
包裹,包含键值对,每个键值对之间用逗号分隔。
{
"name" : "User" ,
"age" : 21 ,
"city" : "Shanghai"
}
数组(Array): 由方括号 []
包裹,包含一组数值、字符串、对象等,每个元素之间用逗号分隔。
[
"apple" ,
"orange" ,
"banana"
]
值(Value): 可以是字符串、数字、布尔值、对象、数组、null
。
{
"name" : "User" ,
"age" : 21 ,
"isStudent" : false ,
"grades" : [ 95 , 85 , 92 ] ,
"address" : {
"street" : "123 Main St" ,
"city" : "Anytown"
} ,
"other" : null
}
# 正确的情况
{
"user001" : {
"age" : 20 ,
"gender" : "male"
} ,
"user002" : {
"age" : 18 ,
"gender" : "female"
}
}
# 错误的情况
{
"user001" : {
"age" : 20 ,
"gender" : "male"
}
}
'''此处就出现了两个对象'''
{
"user002" : {
"age" : 18 ,
"gender" : "female"
}
}
# 错误信息 "JSON standard allows only one top-level value"
json文件中只有双引号作为引号
当使用json.dump
上传的字典数据将自动将引号转为双引号
如果手动输入json数据时,输入了单引号,将会有错误信息提示
JSON standard allows only double quoted string as property key
JSON standard does not allow single quoted strings
import json
python_obj = {'user' : '001' , 'age' : 18 , 'hobby' : []}
with open ("01.json" , "w" , encoding='utf-8' ) as fp:
json.dump(obj=python_obj, fp=fp)
# 写入json文件后将自动转为双引号
{ "user" : "001" , "age" : 18 , "hobby" : [ ] }
当使用 json.load()
方法从 JSON 文件中加载数据时,Python 的 json
模块会灵活地接受 JSON 文件中的字符串,无论是单引号还是双引号。
import json
python_obj = {"user" : '001' , 'age' : 18 , 'hobby' : []}
with open ("01.json" , "w" , encoding='utf-8' ) as fp:
json.dump(obj=python_obj, fp=fp)
with open ('01.json' , 'r' , encoding='utf8' ) as fp:
data = json.load(fp)
print (data)
(3)json.dump
import json
data_dict = {'user' : 1 , 'age' : 20 , 'hobby' : []}
with open ('01.json' , 'w' , encoding='utf8' ) as fp:
json.dump(obj=data_dict, fp=fp, ensure_ascii=False )
# 01. json
{
"user" : 1 ,
"age" : 20 ,
"hobby" : [ ]
}
(4)json.load
with open ('01.json' , 'r' , encoding='utf8' ) as fp:
data = json.load(fp)
print (data, type (data))
(5)json.dumps
将Python对象转换为json字符串
json转换完的字符串类型的字典中的字符串是由 ""
表示的
python_dict = {'user' : 1 , 'age' : 20 , 'hobby' : []}
print (type (python_dict))
json_txt = json.dumps(python_dict)
print (json_txt, type (json_txt))
(6)json.loads
json_txt = '''
{
"user": 1,
"age": 20,
"hobby": []
}
'''
print (type (json_txt))
python_dict = json.loads(json_txt)
print (python_dict, '\n' , type (python_dict))
(7)其他参数
Serialize obj to a JSON formatted str .(字符串表示的json对象)
Skipkeys:
默认值是False
如果dict 的keys内的数据不是python的基本类型(str ,unicode,int ,long,float ,bool ,None )设置为False 时,就会报TypeError的错误。
此时设置成True ,则会跳过这类key
ensure_ascii:
当它为True 的时候
所有非ASCII码字符显示为\uXXXX序列
只需在dump时将ensure_ascii设置为False 即可
此时存入json的中文即可正常显示。
If check_circular is false, then the circular reference check for container types will be skipped and a circular reference will result in an OverflowError (or worse).
If allow_nan is false, then it will be a ValueError to serialize out of range float values (nan, inf, -inf) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (NaN, Infinity, -Infinity).
indent:
应该是一个非负的整型
如果是0 就是顶格分行显示
如果为空就是一行最紧凑显示
否则会换行且按照indent的数值显示前面的空白分行显示
这样打印出来的json数据也叫pretty-printed json
separators:
分隔符
实际上是(item_separator, dict_separator)的一个元组
默认的就是(‘,’,’:’);
这表示dictionary内keys之间用“,”隔开
而KEY和value之间用“:”隔开。
default(obj) is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError.
sort_keys:
将数据根据keys的值进行排序。
To use a custom JSONEncoder subclass (e.g. one that overrides the .default() method to serialize additional types), specify it with the cls kwarg; otherwise JSONEncoder is used.
ensure_ascii = False
:
在 Python 的 json
模块中,ensure_ascii
是 json.dump()
和 json.dumps()
函数的一个可选参数。它是一个布尔值,默认为 True
。
当 ensure_ascii
设置为 True
时,表示确保生成的 JSON 数据中的所有非 ASCII 字符都会被转义为 Unicode 转义序列。这样做是为了确保生成的 JSON 字符串是纯 ASCII 的,适用于大多数场景,尤其是在处理传输或存储时。
当 ensure_ascii
设置为 False
时,表示允许非 ASCII 字符直接保留在生成的 JSON 字符串中,而不进行转义。这在一些特殊需求的情况下可能会更有用,但要注意,生成的 JSON 字符串可能包含非 ASCII 字符,可能在某些情况下导致问题。
当 ensure_ascii
为 True
时,中文字符会以 \uXXXX
的形式进行转义,其中 XXXX
是相应中文字符的 Unicode 编码。这样做是为了确保生成的 JSON 数据是纯 ASCII 的。
import json
python_obj = {"user" : '月亮' , 'age' : 18 , 'hobby' : []}
with open ("01.json" , "w" , encoding='utf-8' ) as fp:
json.dump(obj=python_obj, fp=fp)
# \u6708\u4eae
{ "user" : "\u6708\u4eae" , "age" : 18 , "hobby" : [ ] }
import json
python_obj = {"user" : '月亮' , 'age' : 18 , 'hobby' : []}
with open ("01.json" , "w" , encoding='utf-8' ) as fp:
json.dump(obj=python_obj, fp=fp, ensure_ascii=False )
{ "user" : "月亮" , "age" : 18 , "hobby" : [ ] }
【5】pickle
(1)pickle文件
pickle
序列化后的文件通常使用 .pkl
或 .pickle
作为文件的后缀名。这是一种约定,表示文件中包含经 pickle
序列化的数据。
(2)pickle文件的基本结构
pickle
模块将 Python 对象转换为二进制数据,以便于保存到文件或在网络上传输。这些二进制数据可以包含多个对象的信息,其内部结构是包含对象的层次结构。
在序列化后的文件中,你将看到一系列的二进制数据,它们表示不同层次上的对象。这些数据可以包括 Python 内置类型、自定义类的实例、字典、列表等等。
如果你感兴趣,你可以使用文本编辑器或二进制查看器打开 .pkl
文件,但由于其二进制格式,直接查看可能并不容易理解。更多时候,你会使用 pickle.load()
来反序列化这些数据并还原为 Python 对象。
import pickle
l1 = [1 , 2 , 3 , 4 , 5 ]
s2 = {4 , 5 , 6 , 7 , 8 }
'''列表通过pickle序列化'''
res1 = pickle.dumps(l1)
print (res1)
'''集合通过pickle序列化'''
res2 = pickle.dumps(s2)
print (res2)
with open ('1.pickle' , 'ab' ) as f:
pickle.dump(l1, f)
with open ('1.pickle' , 'ab' ) as f:
pickle.dump(s2, f)
with open ('1.pickle' , 'rb' ) as f1:
data1 = pickle.load(f1)
data2 = pickle.load(f1)
print (data1)
print (data2)
(3)pickle.dump
注:pickle文件是二进制数据,mode只有wb
,rb
和ab
l1 = ['hi' , '你好' ]
with open (file='1.pickle' , mode='wb' ) as f:
pickle.dump(obj=l1, file=f)
(4)pickle.load
l1 = ['hi' , '你好' ]
with open (file='1.pickle' , mode='wb' ) as f:
pickle.dump(obj=l1, file=f)
with open (file='1.pickle' , mode='rb' ) as f:
res = pickle.load(f)
print (res)
(5)其他参数
pickle.dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None):
序列化对象 obj
并将结果写入文件 file
。
protocol
参数指定了序列化的协议版本,如果省略,则默认使用最高协议版本。
fix_imports
参数用于控制是否修复在 Python 2 中由于模块名称更改而导致的导入问题,默认为 True
。
buffer_callback
参数是在 protocol
版本为 5 时可用的回调函数,用于控制缓冲区的分配。
pickle.load(file, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None):
从文件 file
中读取序列化的对象,并返回反序列化的结果。
fix_imports
参数用于控制是否修复在 Python 2 中由于模块名称更改而导致的导入问题,默认为 True
。
encoding
和 errors
参数用于指定读取文件时使用的编码。
buffers
参数是在 protocol
版本为 5 时可用的缓冲区对象。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库