Python 对象序列化

简介: Python 对象序列化
小知识,大挑战!本文正在参与“ 程序员必备小知识”创作活动。

<br/>

引言

将对象的状态信息转换为可以存储或传输的形式的过程叫作序列化

类似地从序列化后的数据转换成相对应的对象叫作 反序列化

本文介绍 Python 将对象序列化和反序化的两个模块

  • pickle
  • json

<br/>

pickle

In [18]: import 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    

<br/>

自定义的对象也能序列化

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]: '男'        

<br/>

注意:pickle 序列化后数据都是字节(bytes)类型

<br/>

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()

<br/>

从文件反序化回对象

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]: '男'

<br/>

pickle 模块虽然可以将对象序列化,但它只适用于 Python 语言,所以不方便数据交换。例如你将数据发给前端, js 则无法将数据转成自己想要的。

<br/>

json

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如 json,因为 json 表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输进行数据交换。

<br/>

json 字符串表示的对象就是 js 的对象,jsonPython 内置的数据类型对应如下:

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

<br/>

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        

<br/>

看看自定义的类对象能不能 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 模块。

<br/>

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"}'

<br/>

也可以在序列化的时候指定一个转换器,可选参数 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"}'

<br/>

这样虽然可以把自定义的类对象转换成 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"}'

<br/>

注意:如果是对象中的属性又嵌套另一个不能直接 json 序列化的对象,使用 __dict__ 属性照样无法正常序列化。

<br/>

尾语

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

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

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

相关文章
|
9天前
|
安全 大数据 程序员
Python operator模块的methodcaller:一行代码搞定对象方法调用的黑科技
`operator.methodcaller`是Python中处理对象方法调用的高效工具,替代冗长Lambda,提升代码可读性与性能。适用于数据过滤、排序、转换等场景,支持参数传递与链式调用,是函数式编程的隐藏利器。
47 4
|
1月前
|
安全 JavaScript Java
Python中None与NoneType的真相:从单例对象到类型系统的深度解析
本文通过10个真实场景,深入解析Python中表示“空值”的None与NoneType。从单例模式、函数返回值,到类型注解、性能优化,全面揭示None在语言设计与实际编程中的核心作用,帮助开发者正确高效地处理“无值”状态,写出更健壮、清晰的Python代码。
163 3
|
1月前
|
Python
解决Python中AttributeError:'image'对象缺少属性'read_file'的问题策略。
通过上述策略综合考虑,您将能够定位问题并确定如何解决它。记住,Python社区很庞大,也很乐于帮助解决问题,因此不要害怕在求助时提供尽可能多的上下文和您已经尝试过的解决方案。
73 0
|
5月前
|
Python
解决Python报错:DataFrame对象没有concat属性的多种方法(解决方案汇总)
总的来说,解决“DataFrame对象没有concat属性”的错误的关键是理解concat函数应该如何正确使用,以及Pandas库提供了哪些其他的数据连接方法。希望这些方法能帮助你解决问题。记住,编程就像是解谜游戏,每一个错误都是一个谜题,解决它们需要耐心和细心。
277 15
|
5月前
|
安全 测试技术 开发者
Python中的“空”:对象的判断与比较
在Python开发中,判断对象是否为“空”是常见操作,但其中暗藏诸多细节与误区。本文系统梳理了Python中“空”的判定逻辑,涵盖None类型、空容器、零值及自定义对象的“假值”状态,并对比不同判定方法的适用场景与性能。通过解析常见误区(如混用`==`和`is`、误判合法值等)及进阶技巧(类型安全检查、自定义对象逻辑、抽象基类兼容性等),帮助开发者准确区分各类“空”值,避免逻辑错误,同时优化代码性能与健壮性。掌握这些内容,能让开发者更深刻理解Python的对象模型与业务语义交集,从而选择最适合的判定策略。
199 5
|
11月前
|
缓存 安全 PHP
PHP中的魔术方法与对象序列化
本文将深入探讨PHP中的魔术方法,特别是与对象序列化和反序列化相关的__sleep()和__wakeup()方法。通过实例解析,帮助读者理解如何在实际应用中有效利用这些魔术方法,提高开发效率和代码质量。
|
5月前
|
人工智能 Python
[oeasy]python083_类_对象_成员方法_method_函数_function_isinstance
本文介绍了Python中类、对象、成员方法及函数的概念。通过超市商品分类的例子,形象地解释了“类型”的概念,如整型(int)和字符串(str)是两种不同的数据类型。整型对象支持数字求和,字符串对象支持拼接。使用`isinstance`函数可以判断对象是否属于特定类型,例如判断变量是否为整型。此外,还探讨了面向对象编程(OOP)与面向过程编程的区别,并简要介绍了`type`和`help`函数的用法。最后总结指出,不同类型的对象有不同的运算和方法,如字符串有`find`和`index`方法,而整型没有。更多内容可参考文末提供的蓝桥、GitHub和Gitee链接。
123 11
|
9月前
|
存储 数据处理 Python
Python如何显示对象的某个属性的所有值
本文介绍了如何在Python中使用`getattr`和`hasattr`函数来访问和检查对象的属性。通过这些工具,可以轻松遍历对象列表并提取特定属性的所有值,适用于数据处理和分析任务。示例包括获取对象列表中所有书籍的作者和检查动物对象的名称属性。
195 2
|
9月前
|
缓存 监控 算法
Python内存管理:掌握对象的生命周期与垃圾回收机制####
本文深入探讨了Python中的内存管理机制,特别是对象的生命周期和垃圾回收过程。通过理解引用计数、标记-清除及分代收集等核心概念,帮助开发者优化程序性能,避免内存泄漏。 ####
208 3
|
10月前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
340 1

热门文章

最新文章