Python 序列化与反序列化

目录

1、基本概念

2、JSON模块

2.1、dumps() 与 loads() 函数

2.2、dump() 与 load() 函数

2.3、bool 、None 类型的序列化与反序列化

3、pickle模块

3.1、dumps() 与 loads() 函数

3.2、dump() 与 load() 函数

1、基本概念

说明:通过文件操作,可将字符串写入到一个本地文件,但是无法将一个对象,如字典,列表,元组直接写入到一个文件里,这是就需要将这个对象进行序列化,然后写入文件。
序列化:把内存中的数据转换为字节序列,保存到文件。

反序列化:从文件的字节序列恢复到内存中。

类比:字符串与 byte 类型之间互相转换常用的 encode() 函数、与 decode() 函数,分别代表着编码与解码。

Python中可序列化数据类型

  • 可序列化:number、str、list、tuple、dict 字典是最常用的序列化数据类型
  • 不可序列化:class 、def (函数与实例化对象)、set 是无法进行序列化的

在Python中有两个模块可以实现序列化和非序列化,分别是json 和 pickle,下面分别说明两者的使用和区别

2、JSON模块

JSON一种轻量级的数据交换标准,JSON的本质是字符串。也是一个通用的序列化模块,通过它可以完成通用化的序列化与反序列化操作。因为几乎所有的编程语言都有json模块,而且他们序列化与反序列化的规则是统一的。

2.1、dumps() 与 loads() 函数

注意:这两个函数不能直接和文件交互,需要将对象序列化后再写入文件,将原数据从文件中读出后再进行反序列化操作。

示例1:序列化操作

import json

# 定义 整型、字符串、列表、元组、字典 五种数据类型 ,用于序列化测试
int_test = 666
str_test = 'test_string'
list_test = [1, 2, 3]
tuple_test = (4, 5, 6)
dict_test = {'Name': '林一', 'Sex': '男', 'Age': '20'}

int_test_json = json.dumps(int_test)
print(int_test_json) # 666

str_test_json = json.dumps(str_test)
print(str_test_json) # "test_string"

list_test_json = json.dumps(list_test)
print(list_test_json) # [1, 2, 3]

tuple_test_json = json.dumps(tuple_test)
print(tuple_test_json) # [4, 5, 6]

dict_test_json = json.dumps(dict_test)
print(dict_test_json) # {"Name": "\u6797\u4e00", "Sex": "\u7537", "Age": "20"}

从执行结果可以看出字典类型的数据类型,经过序列化后。字典变成了字符串的同时,且字典内的 单引号 变成了 双引号,中文也变成了比特类型,并且进行了 encode 。

示例2:反序列化操作

# 反序列化操作
print(json.loads(int_test_json)) # 666
print(json.loads(str_test_json)) # test_string
print(json.loads(list_test_json)) # [1, 2, 3]
print(json.loads(tuple_test_json)) # [4, 5, 6]
print(json.loads(dict_test_json)) # {'Name': '林一', 'Sex': '男', 'Age': '20'}

注意:元组类型经过序列化处理后再通过反序列化还原数据时,会变为列表数据类型。

  • 这是因为 元组类型 是 python 语言中特有的数据类型,json 作为一个通用格式,无法识别元组类型。所以在针对元组类型进行序列化的时候,会先将 元组类型 ,先转为 列表,再进行序列化处理;同样的在进行反序列化处理时,就会将序列化后的 元组类型 ,又转成了 列表类型 。(类型的转换,不影响对数据的使用)

2.2、dump() 与 load() 函数

作用:可以直接和文件交互

示例1:序列化

dict_test = {"Name": "hello", "Sex": "女", "Age": 18}
with open("json_test.txt", "w") as f:
    json.dump(dict_test, f)

示例2:反序列化

with open("json_test.txt", "r") as f:
    content = json.load(f)
    print(f"文件类型是: {type(content)}, 文件内容为: {content}")

2.3、bool 、None 类型的序列化与反序列化

import json
print("-------------------序列化----------------------------")
print(json.dumps(True)) # true
print(json.dumps(False)) # false
print(json.dumps(None)) # null

print("-------------------反序列化----------------------------")
print(json.loads(json.dumps(True))) # True
print(json.loads(json.dumps(False))) # False
print(json.loads(json.dumps(None))) # None

说明:从上述运行结果来看,bool 类型经过序列化处理后,变成了小写的 true、false;而 None 类型则变成了 小写的 null 。经过反序列化之后,bool、None 类型又被还原成了 python 可读的状态。

注意:大多数的编程语言中, bool 类型都是小写的 true、false 。json 作为一个通用的序列化模块,也同样遵循着这种规则。(小写的 true、false 依然是字符串类型。 )

3、pickle模块

说明:pickle模块与json模块一样可以进行序列化与反序列化,区别在于 pickle 是 Python 内置的序列化模块,它只能用于 python 自身来使用,而json模块更加通用,但pickle模块的性能是要比 json 更好的。所以实际使用根据自身需求选择对应的模块进行使用。

3.1、dumps() 与 loads() 函数

注意:区别于 json 模块,pickle 模块的 dumps() 函数 返回的是 byte 类型 ,而 loads() 函数也仅支持 byte 类型的 pickle 序列进行反序列化的操作。

示例1: 序列化与反序列化

import pickle

# 定义 字符串、元组、字典 三种数据类型 ,用于序列化测试
print("-------------------序列化----------------------------")
str_test = 'test_string'
tuple_test = (4, 5, 6)
dict_test = {'Name': '林一', 'Sex': '男', 'Age': '20'}

str_test_pickle = pickle.dumps(str_test)
print(str_test_pickle)

tuple_test_pickle = pickle.dumps(tuple_test)
print(tuple_test_pickle)

dict_test_pickle = pickle.dumps(dict_test)
print(dict_test_pickle)

print("-------------------反序列化----------------------------")
print(pickle.loads(str_test_pickle))
print(pickle.loads(tuple_test_pickle))
print(pickle.loads(dict_test_pickle))

3.2、dump() 与 load() 函数

作用:dump()函数能一个接着一个地将几个对象序列化存储到同一个文件中,随后调用load()来以同样的顺序反序列化读出这些对象。

参数protocol:是序列化模式,默认是0(ASCII协议,表示以文本的形式进行序列化),protocol的值还可以是1和2(1和2表示以二进制的形式进行序列化。其中,1是老式的二进制协议;2是新二进制协议)。

示例:序列化与反序列化

import pickle
dict_test = {"Name": "hello", "Sex": "女", "Age": 18}
with open("pickle_test.txt", "wb") as f:
    pickle.dump(dict_test, f, 0)

with open("pickle_test.txt", "rb") as f:
    content = pickle.load(f)
    print(f"文件类型是: {type(content)}, 文件内容为: {content}")

注意:

  • 1、由于写入文件和从文件读出都是以二进制的形式,所以,读写是的模式必须是:wb, rb.
  • 2、为避免写入文件的内容乱码,在dump()里加上第三个参数,设为0(ASCII协议).

  • 22
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值