python json序列化模块

一、json

Json模块提供了四个功能:dumps、dump、loads、load

1、前景

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

序列化的目的

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

在Python中,能够进行序列化的前提是被序列化的对象必须是JSON兼容的数据类型。JSON兼容的数据类型包括:

  1. 字典(Dictionary):键值对的集合,键必须是字符串类型。
  2. 列表(List):有序的元素集合。
  3. 字符串(String):由一系列字符组成的文本。
  4. 数字(Number):包括整数(int)和浮点数(float)。
  5. 布尔值(Boolean):表示真或假的值,即True或False。
  6. None:表示空值或缺失值的特殊类型。

2、loads和dumps(反序列化和序列化)

也可以处理嵌套的数据类型

序列化,将字典序列化成一个字符串

json.dumps(dic)

dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic = json.dumps(dic)  # 序列化:将一个字典转换成一个字符串
print(type(str_dic), str_dic)  # <class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
# 注意,json转换完的字符串类型的字典中的字符串是由""表示的

反序列化,将字符串转成字典

json.loads(str_dic)

dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic = json.dumps(dic)
dic2 = json.loads(str_dic)  # 反序列化:将一个字符串格式的字典转换成一个字典
# 注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(type(dic2), dic2)  # <class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

序列化字符串

import json
string_data = 'Hello, World!'
# 序列化字符串
json_str = json.dumps(string_data)
print(json_str)
# 反序列化
res = json.loads(json_str)
print(res)

3、load和dump(反序列化读和序列化写)

json.dump(data, f),data要是可迭代的容器,字典或者列表

注意⚠️:

使用 json.dump() 方法来序列化一个字符串写入文件时,需要将字符串包装在一个可迭代的容器中,例如列表或字典

例如字符串:

import json

string_data = "Hello, World!"

# 创建包含字符串的字典
data = {'message': string_data}

# 序列化字符串并写入文件
with  open('output.json', 'w') as f:
    json.dump(data, f)

列表:列表是可迭代对象可以直接序列化写

import json

list_data = [1, 2, 3, 4, 5]

# 序列化列表并写入文件
with  open('output.json', 'w') as f:
    json.dump(list_data, f)

序列化写字典

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

with  open('a.txt', 'r') as f:
    dic2 = json.load(f)  # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
    print(type(dic2), dic2) # <class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

案例:

登录注册时候,数据的写入和读取

json.load(f) 函数用于从文件中加载 JSON 数据,但是它只能读取一个合法的 JSON 对象,当文本 f 中,存在多个 JSON 对象,导致出现错误。

要解决这个问题,将文本中的每个 JSON 对象分别解析处理。可以使用 json.loads() 函数逐行解析每个 JSON 对象,然后进行处理。

换行处理

json.dump(data, f, ensure_ascii=True)
f.write('\n')

代码如下:

import json

username, password, role = input('Username:').split()
data = {
    'username': username,
    'password': password,
    'role': role
}

with  open('user_data.txt', "r", encoding='utf-8') as f:
    lines = f.readlines()
    for line in lines:
        line = line.strip()  # 去除行首行尾的空白字符
        obj = json.loads(line)
        if username == obj['username']:
            print('用户已经注册过了!')
            break
    else:
        with  open('user_data.txt', "a", encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=True)
            f.write('\n')
            # f.write(f"{username},{password},{role}\n")
            print(f"用户 {data['username']} 已成功注册!")

with  open('user_data.txt', "r", encoding="utf-8") as f:
    lines = f.readlines()
    for line in lines:
        line = line.strip()  # 去除行首行尾的空白字符
        if line:  # 确保行不为空
            try:
                obj = json.loads(line)
                # 在这里对每个 JSON 对象进行处理
                print(obj, type(obj))
            except json.JSONDecodeError:
                print('无效的 JSON 数据:', line)

4、ensure_ascii关键字参数

汉字的序列化后为\u56fd\u7c4d,使用ensure_ascii关键字参数可以以中文写入

with  open('a.txt', 'a') as f:
    json.dump({'国籍': '中国'}, f)  # 序列化方式写文件

    ret = json.dumps({'国籍': '中国'})
    f.write(ret + '\n')  # 正常通用方式写文件、
    # {"\u56fd\u7c4d": "\u4e2d\u56fd"}{"\u56fd\u7c4d": "\u4e2d\u56fd"}

    json.dump({'国籍': '美国'}, f, ensure_ascii=False)  # 取消编码写入

    ret = json.dumps({'国籍': '美国'}, ensure_ascii=False)
    f.write(ret + '\n')
    # {"国籍": "美国"}{"国籍": "美国"}

5、格式化输出(indent)

json.dumps()json 模块中的一个函数,用于将 Python 对象序列化为 JSON 字符串。它提供了一些参数来控制序列化的行为。下面是对 json.dumps() 中的常用序列化参数的解释:

  • sort_keys(可选参数):设置为 True 时,将按照键的字母顺序对字典进行排序,默认为 False

  • indent(可选参数):指定缩进级别,用于生成格式化的 JSON 字符串。可以是一个整数,表示缩进的空格数,或者是一个字符串,表示使用的缩进字符(例如,\t 表示使用制表符进行缩进)。默认为 None,表示不进行格式化,生成紧凑的 JSON 字符串。

  • separators(可选参数):指定分隔符,用于控制生成的 JSON 字符串中的各个部分之间的分隔符。它是一个包含两个字符串的元组,第一个字符串用于分隔键和值之间的分隔符,默认为 ",";第二个字符串用于分隔键值对之间的分隔符,默认为 ":"

  • ensure_ascii(可选参数):设置为 True 时,所有非 ASCII 字符将被转义为 ASCII 编码的字符序列,默认为 True。如果需要生成包含非 ASCII 字符的 JSON 字符串,可以将其设置为 False

import json

data = {'username': ['李四', '银行职员'], 'sex': 'male', 'age': 16}
json_dic2 = json.dumps(data, sort_keys=True, indent=2, separators=(',', ':'), ensure_ascii=False)
print(json_dic2)

# 输出结果

  • sort_keys=True:按照键的字母顺序对字典进行排序。
  • indent=2:使用两个空格进行缩进,生成格式化的 JSON 字符串。
  • separators=(',', ':'):使用逗号和冒号作为分隔符。
  • ensure_ascii=False:允许非 ASCII 字符在生成的 JSON 字符串中原样显示。

二、pickle 模块

1、用于序列化的两个模块

  • json,用于字符串 和 python数据类型间进行转换 (可以跨语言使用)
  • pickle,用于python特有的类型 和 python的数据类型间进行转换
  • pickle 能够转换所有的pyhton数据类型、序列化后为二进制
  • json只能转换部分的python数据类型

 

2、pickle模块提供了四个功能:dumps(序列化)、dump(序列化写)、loads(反序列化)、load(反序列化读)

(不仅可以序列化字典,列表...可以把python中任意的数据类型序列化)

序列化和反序列化

import pickle

dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic = pickle.dumps(dic)
print(str_dic)  # 一串二进制内容
# b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x。。。

dic2 = pickle.loads(str_dic)
print(dic2)  # 字典 {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

3、序列化写、读

import pickle
import time

struct_time = time.localtime(1000000000)
print(struct_time)
with  open('a.txt', 'wb') as f:
    pickle.dump(struct_time, f)

with  open('a.txt', 'rb') as f1:
    struct_time2 = pickle.load(f1)
    print(struct_time2.tm_year)

 

posted @ 2023-06-12 16:00  凡人半睁眼  阅读(172)  评论(0编辑  收藏  举报