Python常用库(四):json序列化和反序列

news/2024/7/24 2:32:28 标签: 后端

1. 标准库:json

1.1 参数说明

参数说明
skipkeys如果为True的话,则只能是字典对象,否则会TypeError错误, 默认False
ensure_ascii确定是否为ASCII编码,设置True时,汉字会正常显示
check_circular循环类型检查,如果为True的话
allow_nan确定是否为允许的值
indent当设置True时,会以美观的方式来打印Json
separators对象分隔符,默认为,
sort_keys当设置True字时,字典对象会按照键的ASCII码来排序
if __name__ == '__main__':
    print("-------------- 以默认形式打印 --------------")
    mapVar = {"name""张三""age"28"gender""男""home""北京"}
    # 以默认形式打印
    print(json.dumps(mapVar))
    # 以美观的形式打印
    print("-------------- 以美观的形式打印 --------------")
    print(json.dumps(mapVar, indent=True, ensure_ascii=False))
    # 当设置True字时,字典对象会按照键的ASCII码来排序
    print("-------------- 字典对象会按照键ASCII码来排序  --------------")
    print(json.dumps(mapVar, indent=True, ensure_ascii=False, sort_keys=True))
    
# ************************** 输出 **************************   
-------------- 以默认形式打印 --------------
{"name""\u5f20\u4e09""age"28"gender""\u7537""home""\u5317\u4eac"}
-------------- 以美观的形式打印 --------------
{
 "name""张三",
 "age"28,
 "gender""男",
 "home""北京"
}
-------------- 字典对象会按照键ASCII码来排序  --------------
{
 "age"28,
 "gender""男",
 "home""北京",
 "name""张三"
}

1.2 变量转Json

import json

if __name__ == '__main__':
    listVar = [123456789]
    # 列表转json
    print('列表转json:', json.dumps(listVar))
    # map 转json
    mapVar = {'name''张三''age'18}
    print('map转json:', json.dumps(mapVar))
    print('map转json-汉字不转义:', json.dumps(mapVar, ensure_ascii=False))
    # 列表map转json
    listMapVar = [
        {'name''张三''age'18},
        {'name''李四''age'33},
        {'name''王五''age'20},
    ]
    print('列表map转json:', json.dumps(listMapVar, ensure_ascii=False))

# ----------------- 输出 ---------------------
列表转json: [123456789]
map转json: {"name""\u5f20\u4e09""age"18}
map转json-汉字不转义: {"name""张三""age"18}
列表map转json: [{"name""张三""age"18}, {"name""李四""age"33}, {"name""王五""age"20}]

1.3 Json转变量

import json

if __name__ == '__main__':
    # json转列表
    listJsonStr = '[1, 2, 3, 4, 5, 6, 7, 8, 9]'
    res = json.loads(listJsonStr)
    print('json转列表:{} type:{}'.format(res, type(res)))
    # json转字典
    dictJsonStr = '{"name": "张三", "age": 18}'
    res2 = json.loads(dictJsonStr)
    print('json转字典:{} type:{}'.format(res2, type(res2)))
    
# ----------------- 输出 ---------------------
json转列表:[123456789] type:<class 'list'>
json转字典:
{'name''张三''age'18} type:<class 'dict'>

1.4 读写Json文件

import json
import os
import time

if __name__ == '__main__':
    # json文件位置
    jsonFile = os.path.join(os.getcwd(), "test.json")
    if not os.path.exists(jsonFile):
        # 创建文件
        open(jsonFile, "w").close()

    # 写json文件
    with open(jsonFile, "w"as f:
        stu = {'name''张三''time': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}
        # 写入
        print("写入json内容:", stu)
        json.dump(stu, f, ensure_ascii=False)

    time.sleep(3)
    print("--------------------- 暂停3秒 ---------------------")
    # 读取json文件内容
    with open(jsonFile, "r"as f:
        result = json.load(f)
        print("读取json内容:", result)
 
# ----------------- 输出 ---------------------
写入json内容: {'name''张三''time''2023-09-01 00:02:24'}
--------------------- 暂停3秒 ---------------------
读取json内容: {'name''张三''time''2023-09-01 00:02:24'}

1.5 类对象转Json

import json

class Student:
    def __init__(self, name: str, age: int, phone: str):
        self.name = name
        self.age = age
        self.__phone = phone

    @property
    def tojson(self):
        return {
            'name': self.name,
            'age': self.age,
            'phone': self.__phone
        }


if __name__ == '__main__':
    stu = Student("张三"22"17600000111")
    print("*************** 第一种方式: __dict__ *****************")
    print(json.dumps(stu.__dict__, indent=True, ensure_ascii=False))

    print("*************** 第二种方式: 自定义方法 *****************")
    print(json.dumps(stu.tojson, indent=True, ensure_ascii=False))
 
# -------------------- 输出 --------------------
*************** 第一种方式: __dict__ *****************
{
 "name""张三",
 "age"22,
 "_Student__phone""17600000111"
}
*************** 第二种方式: 自定义方法 *****************
{
 "name""张三",
 "age"22,
 "phone""17600000111"
}

1.6 Json转类对象

if __name__ == '__main__':
    jsonString = '{"name":"张三","age":22,"phone":"177777777777"}'
    jsonData = json.loads(jsonString)
    s = Student(jsonData['name'], jsonData['age'], jsonData['phone'])
    print("s.type: ", type(s))
    print("s.name: ", s.name)
    print("s.age: ", s.age)
    
# -------------------- 输出 --------------------
s.type:  <class '__main__.Student'>
s.name:
  张三
s.age:  22

2. 开源库:orjosn

orjson是一个JSON库,相较于Python原生的JSON库,它的功能更加丰富、效率更高。

Github(截止当前4.9k): https://github.com/ijl/orjson

5.1 安装

# 使用pip 安装
$ pip install --upgrade orjson
# 使用
$ conda install orjson

5.2 变量转json

import orjson

if __name__ == '__main__':
    listVar = [123456789]
    # 列表转json
    listJson = orjson.dumps(listVar)
    print('列表转json:', listJson, 'type:', type(listJson))
    print('结果bytes转str:', listJson.decode('utf-8'))

    # map 转json
    mapVar = {'name''张三''age'18}
    mapJson = orjson.dumps(mapVar)
    print('map转json:', mapJson, 'type:', type(mapJson))
    print('结果bytes转str:', mapJson.decode('utf-8'))

    # 列表map转json
    listMapVar = [
        {'name''张三''age'18},
        {'name''李四''age'33},
        {'name''王五''age'20},
    ]
    listMapVarJson = orjson.dumps(listMapVar)
    print('列表map转json:', listMapVarJson, 'type:', type(listMapVarJson))
    print('结果bytes转str:', listMapVarJson.decode('utf-8'))
    
# -------------------- 输出 -------------------
列表转json: b'[1,2,3,4,5,6,7,8,9]' type: <class 'bytes'>
结果bytesstr:
 [1,2,3,4,5,6,7,8,9]
map转json: b'{"name":"\xe5\xbc\xa0\xe4\xb8\x89","age":18}' type: <class 'bytes'>
结果bytesstr:
 {"name":"张三","age":18}
列表map转json: b'[{"name":"\xe5\xbc\xa0\xe4\xb8\x89","age":18},{"name":"\xe6\x9d\x8e\xe5\x9b\x9b","age":33},{"name":"\xe7\x8e\x8b\xe4\xba\x94","age":20}]' type: <class 'bytes'>
结果bytesstr:
 [{"name":"张三","age":18},{"name":"李四","age":33},{"name":"王五","age":20}]

@注: 通过上面示例可以发现,序列化后的数据类型为bytes,需要通过x.decode('utf-8')转str

5.3 json转变量

if __name__ == '__main__':
    # json转列表
    listJsonStr = '[1, 2, 3, 4, 5, 6, 7, 8, 9]'
    res = orjson.loads(listJsonStr)
    print('json转列表:{} type:{}'.format(res, type(res)))
    # json转字典
    dictJsonStr = '{"name": "张三", "age": 18}'
    res2 = orjson.loads(dictJsonStr)
    print('json转字典:{} type:{}'.format(res2, type(res2)))
    # json转字典列表
    mapListJsonStr = '''[{"name":"张三","age":18},{"name":"李四","age":33},{"name":"王五","age":20}]'''
    res3 = orjson.loads(mapListJsonStr)
    print('json转字典列表:{} type:{}'.format(res3, type(res3)))

# --------------------------- 输出 -------------------------- 
json转列表:[123456789] type:<class 'list'>
json转字典:
{'name''张三''age'18} type:<class 'dict'>
json转字典列表:
[{'name''张三''age'18}, {'name''李四''age'33}, {'name''王五''age'20}] type:<class 'list'>

5.4 类对象转json

import dataclasses
import orjson

@dataclasses.dataclass
class Student:
    def __init__(self, name: str, age: int, phone: str):
        self.name = name
        self.age = age
        self.__phone = phone

if __name__ == '__main__':
    # json转列表
    stu = Student("小英"18"17600000000")
    jsonRes = orjson.dumps(stu).decode("utf-8")
    print("jsonRes:", jsonRes, "type", type(jsonRes))

# --------------------------- 输出 --------------------------
jsonRes: {"name":"小英","age":18} type <class 'str'>

@提示: 上面是实例会发现,私有属性不会被序列化成json

@注:使用orjson把类转json时,需要给类加上装饰器: @dataclasses.dataclass,否则会报下面错误:

Traceback (most recent call last): File "/Users/liuqh/ProjectItem/PythonItem/python-learn/main.py", line 26, in <module> jsonRes = orjson.dumps(stu).decode("utf-8") ^^^^^^^^^^^^^^^^^ TypeError: Type is not JSON serializable: Student

5.5 嵌套类对象转json

import dataclasses
import typing
from dataclasses import field
import orjson

@dataclasses.dataclass
class Score:
    key: str
    value: int = field(default=0)

@dataclasses.dataclass
class Student:
    score: typing.List[Score]

    def __init__(self, name: str, scoreList: typing.List[Score]):
        self.name = name
        self.score = scoreList

if __name__ == '__main__':
    # json转列表
    stu = Student("小英", [Score("语文"88), Score("英语"75), Score("数学"92)])
    jsonRes = orjson.dumps(stu).decode("utf-8")
    print("jsonRes:", jsonRes, "type", type(jsonRes))
    
# --------------------------- 输出 --------------------------    
jsonRes: {"name":"小英","score":[{"key":"语文","value":88},{"key":"英语","value":75},{"key":"数学","value":92}]} type <class 'str'>

5.6 OPTION选项使用

参数说明
orjson.OPT_INDENT_2美化json打印输出
orjson.OPT_SORT_KEYS可以对序列化后的结果自动按照键进行排序
orjson.OPT_PASSTHROUGH_DATETIME结合default对日期格式做处理
import orjson
from datetime import datetime

def formatTimeHandler(obj):
    if isinstance(obj, datetime):
        return obj.strftime('%Y-%m-%d %H:%M:%S')

if __name__ == '__main__':
    listMapVar = {'name''张三''age'18'home''北京昌平''sex''男'}
    # 美化和排序
    jsonRes = orjson.dumps(listMapVar, option=orjson.OPT_INDENT_2 | orjson.OPT_SORT_KEYS).decode("utf-8")
    print(jsonRes)
    # 时间格式化
    timeMapVar = {'time': datetime.now()}
    r2 = orjson.dumps(timeMapVar, option=orjson.OPT_PASSTHROUGH_DATETIME, default=formatTimeHandler).decode("utf-8")
    print(r2)
# --------------------------- 输出 -------------------------- 
{
  "age"18,
  "home""北京昌平",
  "name""张三",
  "sex""男"
}
{"time":"2023-09-05 00:09:19"}

更多使用方法,参见https://github.com/ijl/orjson

本文由 mdnice 多平台发布


http://www.niftyadmin.cn/n/4999922.html

相关文章

【MySQL】MySQL 慢SQL如何避险

我们在日常开发中&#xff0c;一定遇见过某些SQL执行较慢的情况&#xff0c;我们俗称“慢SQL”&#xff0c;如果你对系统的接口性能要求较高的话&#xff0c;一定不会放过这种SQL&#xff0c;肯定会想办法进行解决&#xff0c;那么&#xff0c;导致慢 SQL 出现的原因&#xff0…

如何打war包,并用war包更新服务器版本

1.打包&#xff0c;我用的maven打包 先执行clean将已经生成的包清除掉 清除完&#xff0c;点package进行打包 控制台输出success&#xff0c;证明打包成功了 文件名.war的后缀就是生成的war包 2.将war包上传致服务器 一般会在war包加上日期版本上传至服务器 解压上传的war…

LinkedList(4):多线程LinkedList 不安全情况

多线程不安全演示&#xff0c;线程越多&#xff0c;现象越明显&#xff0c;这边只启了四个线程。 package com.example.demo;import java.util.LinkedList; import java.util.UUID;public class LInkedListThread {public static void main(String[] args) {final LinkedList&…

【系统编程】线程池以及API接口简介

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

Java迷宫问题

迷宫问题&#xff1a; 问题&#xff1a; /*迷宫问题 &#xff1a; 让小球从左上角开始 到达右上角 绕过障碍物求最短路径这里*号是障碍物的意思* * * * * * ** ** * ** * * ** ** ** ** * * * * * *思路 &#xff…

ApiPost7使用介绍 | HTTP Websocket

一、基本介绍 创建项目&#xff08;团队下面可以创建多个项目节点&#xff0c;每个项目可以创建多个接口&#xff09;&#xff1a; 参数描述库&#xff08;填写参数时自动填充描述&#xff09;&#xff1a; 新建环境&#xff08;前置URL、环境变量很有用&#xff09;&#x…

【科普向】Jmeter 如何测试接口保姆式教程

现在对测试人员的要求越来越高&#xff0c;不仅仅要做好功能测试&#xff0c;对接口测试的需求也越来越多&#xff01;所以也越来越多的同学问&#xff0c;怎样才能做好接口测试&#xff1f; 要真正的做好接口测试&#xff0c;并且弄懂如何测试接口&#xff0c;需要从如下几个…

职责链设计模式

职责链模式又叫命令链、CoR、Chain of Command、Chain of Responsibility。 该模式允许你将请求沿着处理者链进行发送&#xff0c;使多个对象都可以处理请求&#xff0c;每个对象有权决定处理或传递给下个节点。 客户端&#xff1a;用来定义职责链条。 处理者&#xff1a;声明…