Python 对象序列化与反序列化:pickle 与 json 模块详解

蓝鲸
蓝鲸
发布时间:2026-10-14| 6人浏览过
原创

本文深入解析 Python 中对象序列化的两种核心方式:pickle 与 json。pickle 适用于 Python 内部数据交换,支持自定义对象但仅限 Python 环境;json 则提供跨语言标准格式,便于网络传输与存储。文章详细对比两者差异,并通过代码示例演示如何处理自定义类的序列化问题,包括使用 default 参数和 __dict__ 属性等技巧。

引言

序列化是指将对象的状态信息转换为可存储或可传输格式的过程。

反之,将序列化后的数据还原为原始对象的过程称为反序列化。

本文将介绍 Python 中用于实现对象序列化和反序列化的两个主要模块。

  • pickle
  • json

pickle 模块详解


# 序列化
In [19]: num = 66

In [20]: s = 'python'

In [21]: pi = 3.14

In [22]: li = [1, 2, 3]

In [27]: b_num = pickle.dumps(num)

In [28]: b_s = pickle.dumps(s)

In [29]: b_pi = pickle.dumps(pi)

In [30]: b_li = pickle.dumps(li)

In [31]: b_num
Out[31]: b'\x80\x03KB.'

In [32]: b_s
Out[32]: b'\x80\x03X\x06\x00\x00\x00pythonq\x00.'

In [33]: b_pi
Out[33]: b'\x80\x03G@\t\x1e\xb8Q\xeb\x85\x1f.'

In [34]: b_li
Out[34]: b'\x80\x03]q\x00(K\x01K\x02K\x03e.'
    
In [35]: type(b_li)
Out[35]: bytes
    
# 反序列化    
In [47]: pickle.loads(b_num)
Out[47]: 66

In [48]: pickle.loads(b_s)
Out[48]: 'python'

In [49]: pickle.loads(b_pi)
Out[49]: 3.14

In [50]: li = pickle.loads(b_li)

In [51]: li
Out[51]: [1, 2, 3]

In [52]: type(li)
Out[52]: list    

使用 pickle 模块,不仅可以序列化内置数据类型,还能对自定义的对象进行序列化。


class User:
    
    def __init__(self, name, sex):
        self.name = name
        self.sex = sex
        
In [38]: user = User('hui', '男')

In [39]: b_user = pickle.dumps(user)

In [40]: b_user
Out[40]: b'\x80\x03c__main__\nUser\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00huiq\x04X\x03\x00\x00\x00sexq\x05X\x03\x00\x00\x00\xe7\x94\xb7q\x06ub.'

In [41]: type(b_user)
Out[41]: bytes

In [42]: user = pickle.loads(b_user)

In [43]: type(user)
Out[43]: __main__.User

In [44]: user.name
Out[44]: 'hui'

In [45]: user.sex
Out[45]: '男'        

需要注意的是,pickle 序列化后的结果均为字节(bytes)类型。

此外,pickle 模块还支持将对象序列化并保存到文件中,随后可以从文件中反序列化回对象。


import pickle

class User:
    
    def __init__(self, name, sex):
        self.name = name
        self.sex = sex
        
user = User('ithui', '男')
f = open('user.txt', mode='wb')
pickle.dump(user, f)
f.close()

从文件读取并反序列化对象的操作示例如下。


In [3]: f = open('user.txt', 'rb')
   ...: user = pickle.load(f)
   ...: f.close()
   ...: 
In [4]: user
Out[4]: <__main__.User at 0x16c58ebef08>

In [5]: user.name
Out[5]: 'ithui'

In [6]: user.sex
Out[6]: '男'

尽管 pickle 模块能够完成对象序列化,但它仅适用于 Python 语言环境,因此不利于跨平台或跨语言的数据交换。例如,若将数据发送给前端,js 无法直接解析这种格式。

json 模块详解

若需在不同编程语言之间传递对象,必须将其序列化为标准格式,例如 json。因为 json 表示为字符串,可被所有语言读取,并方便地存储到磁盘或通过网路传输进行数据交换。

json 字符串表示的对象即为 js 对象,json 与 Python 内置数据类型的对应关系如下。

JSON类型 Python类型
{} dict
[] list
"string" 'str' 或 u'unicode'
3.14 int 或 float
true / false True / False
null None

In [7]: import json

In [8]: info_dict = {
   ...:     'name': 'hui',
   ...:     'age': 22,
   ...:     'is_admin': True,
   ...:     'hobbies': ['下象棋', '写代码'],
   ...:     'other': None
   ...: }

In [9]: info_json = json.dumps(info_dict)

In [10]: info_json
Out[10]: '{
    		"name": "hui", 
    		"age": 22, 
             "is_admin": true, 
             "hobbies": ["\\u4e0b\\u8c61\\u68cb", "\\u5199\\u4ee3\\u7801"], 
             "other": null
        }'
   
# 对应的反序列化
In [16]: info_d = json.loads(info_json)

In [17]: info_d
Out[17]:
{'name': 'hui',
 'age': 22,
 'is_admin': True,
 'hobbies': ['下象棋', '写代码'],
 'other': None}

In [18]: type(info_d)
Out[18]: dict        

接下来探讨自定义类对象是否可以进行 json 序列化。


In [21]: import json

In [22]: class User:
    ...:
    ...:     def __init__(self, name, sex):
    ...:         self.name = name
    ...:         self.sex = sex
    ...:

In [23]: user = User('ithui', '男')

In [24]: json.dumps(user)
    
TypeError: Object of type User is not JSON serializable    

系统报错指出 User 对象无法直接进行 json 序列化。然而,确实存在方法使自定义对象转换为 json 格式。

基本思路是先将 User 对象转换为可被 json 序列化的结构,例如 dict,然后再将该结构传递给 json 模块。


In [28]: def user2dict(obj):
    ...:     return {'name': obj.name, 'sex': obj.sex}
    ...:
    ...:

In [29]: user = User('ithui', '男')

In [30]: user_dict = user2dict(user)

In [31]: user_dict
Out[31]: {'name': 'ithui', 'sex': '男'}

In [32]: user_json = json.dumps(user_dict)

In [33]: user_json
Out[33]: '{"name": "ithui", "sex": "\\u7537"}'

也可以在序列化时指定一个转换器,通过可选参数 default 将任意对象转换为可序列化为 JSON 的对象。只需为 User 编写一个转换函数,并将其传入即可。


In [28]: def user2dict(obj):
    ...:     return {'name': obj.name, 'sex': obj.sex}
    ...:
    ...:
        
In [34]: user_json = json.dumps(user, default=user2dict)

In [35]: user_json
Out[35]: '{"name": "ithui", "sex": "\\u7537"}'

虽然这种方法可将自定义类对象转换为 json,但为不同类定制转换器既重复又繁琐。因此,可以利用每个类的 __dict__ 属性进行序列化,该属性是一个 dict 对象,用于存储实例变量。需注意少数例外情况,例如定义了 __slots__ 的 class。


In [36]: user.__dict__
Out[36]: {'name': 'ithui', 'sex': '男'}
    
In [41]: json.dumps(user.__dict__)
Out[41]: '{"name": "ithui", "sex": "\\u7537"}'

注意:若对象中的属性嵌套了另一个无法直接 json 序列化的对象,仅使用 __dict__ 属性同样无法成功序列化。

尾语

✍ 用 Code 谱写世界,让生活更有趣。❤️

✍ 万水千山总是情,点赞再走行不行。❤️

✍ 码字不易,还望各位大侠多多支持。❤️

到此这篇关于 Python 对象序列化详细解析的文章就介绍到这了,更多相关 Python 对象序列化内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。