Skip to content

序列化有关模块

将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化

序列化的目的

1、以某种存储形式使自定义对象持久化 2、将对象从一个地方传递到另一个地方 3、使程序更具维护性

urllib.parse

url 中的?后面的内容称为 search

如百度搜索https://www.baidu.com/s?wd=关键字, 其中的wd=关键字(事实上中文会被重新编码不会是这个关键字

  • urllib.parse.urlencode 序列化
  • urllib.parse.parse_qs 反序列化
python
import urllib.parse

parameters = {"name": "John Doe", "age": "33"}
qs = urllib.parse.urlencode(parameters)
# qs值为"name=John+Doe&age=33"

反序列化返回类型为dict[str, list[str]]

python
urllib.parse.parse_qs("name=John&name=Doe&age=33")
# {'name': ['John', 'Doe'], 'age': ['33']}

json 模块

json模块主要提供了 2 个功能:

  • dumps() 序列化
  • loads() 反序列化
python
import json

dic = {"k1": "v1", "k2": "v2", "k3": "v3"}

str_dic = json.dumps(dic)  # 序列化:将一个字典转换成一个字符串
type(str_dic)
# <class 'str'>
str_dic
# '{"k3": "v3", "k1": "v1", "k2": "v2"}'

dic2 = json.loads(str_dic)  # 反序列化:将一个字符串格式的字典转换成一个字典
dic2
# {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

list_dic = [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
str_dic = json.dumps(list_dic)  # 也可以处理嵌套的数据类型
str_dic
# '[1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]'
list_dic2 = json.loads(str_dic)
# [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]

json 字符串中的引号只能用双引号("

dump()load()

python
import json

f = open("json_file", "w")
dic = {"k1": "v1", "k2": "v2", "k3": "v3"}
json.dump(dic, f)  # dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
f.close()

f = open("json_file")
dic2 = json.load(
    f
)  # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close()
print(type(dic2), dic2)
  • ensure_ascii参数

    当它为 True 的时候,所有非 ASCII 码字符显示为\uXXXX 序列,只需在 dump 时将 ensure_ascii 设置为 False 即可,此时存入 json 的中文即可正常显示

    python
    import json
    
    f = open("file", "w")
    json.dump({"国籍": "中国"}, f)
    ret = json.dumps({"国籍": "中国"})
    f.write(ret + "\n")
    json.dump({"国籍": "美国"}, f, ensure_ascii=False)
    ret = json.dumps({"国籍": "美国"}, ensure_ascii=False)
    f.write(ret + "\n")
    f.close()
  • separators参数

    实际上是(item_separator, dict_separator)的一个元组,
    默认的就是(', ', ': '),注意,它含有空格。
    这表示字典内 keys 之间用,隔开,而 key 和 value 之间用:隔开。

  • Skipkeys参数

    默认值是 False,
    当含有非基本类型(str,unicode,int,long,float,bool,None),就会报TypeError的错误。
    此时设置成 True,则会跳过这些类

  • sort_keys参数

    是否对字典排序(按 ASCII)

  • indent参数

    缩进显示的缩进数,如果不为 0,会生成 pretty-printed json。

pickle 模块

pickle模块提供了四个功能:

  • dumps、dump(序列化,存)
  • loads(反序列化,读)
  • load  (不仅可以序列化字典,列表...可以把 python 中任意的数据类型序列化
python
import pickle

dic = {"k1": "v1", "k2": "v2", "k3": "v3"}
str_dic = pickle.dumps(dic)
print(str_dic)  # 一串二进制内容

dic2 = pickle.loads(str_dic)
print(dic2)  # 字典

import time

struct_time = time.localtime(1000000000)
print(struct_time)
f = open("pickle_file", "wb")
pickle.dump(struct_time, f)
f.close()

f = open("pickle_file", "rb")
struct_time2 = pickle.load(f)
print(struct_time2.tm_year)

shelve 模块

shelve模块是种简单的数据存储方案,它只有一个函数就是 open(),这个函数接收一个参数就是文件名,并且文件名必须是.bat 类型的。然后返回一个 shelf 对象,你可以用它来存储东西,它就像一个普通的字典,key 必须为字符串,而值可以是 python 所支持的数据类型 ,当你存储完毕的时候,就调用 close 函数来关闭。
把 open 方法的writeback参数的值赋为 True,这样的话,你 open 后所有的内容都将在 cache 中,当你 close 的时候,将全部一次性写到硬盘里面。如果数据量不是很大的时候,建议这么做。

写入

python
import shelve
import datetime

info = {"name": "bigberg", "age": 22}
name = ["Apoll", "Zous", "Luna"]
t = datetime.datetime.now()

with shelve.open("shelve.txt") as f:
    f["name"] = name  # 持久化列表
    f["info"] = info  # 持久化字典
    f["time"] = t  # 持久化时间类型

执行代码后会生成 3 个文件:shelve.txt.bakshelve.txt.datshelve.txt.dir

读取

python
import shelve

with shelve.open("shelve.txt") as f:
    n = f.get("name")
    i = f.get("info")
    now = f.get("time")

print(n)
print(i)
print(now)

# 输出
"""
['Apoll', 'Zous', 'Luna']
{'age': 22, 'name': 'bigberg'}
2017-07-08 11:07:34.865022
"""