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": "u5f20u4e09", "age": 28, "gender": "u7537", "home": "u5317u4eac"}
-------------- 以美观的形式打印 --------------
{
"name": "张三",
"age": 28,
"gender": "男",
"home": "北京"
}
-------------- 字典对象会按照键ASCII码来排序 --------------
{
"age": 28,
"gender": "男",
"home": "北京",
"name": "张三"
}
1.2 变量转Json
import json
if __name__ == '__main__':
listVar = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 列表转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: [1, 2, 3, 4, 5, 6, 7, 8, 9]
map转json: {"name": "u5f20u4e09", "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转列表:[1, 2, 3, 4, 5, 6, 7, 8, 9] 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
2.1 安装
# 使用pip 安装
$ pip install --upgrade orjson
# 使用
$ conda install orjson
2.2 变量转json
import orjson
if __name__ == '__main__':
listVar = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 列表转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'>
结果bytes转str: [1,2,3,4,5,6,7,8,9]
map转json: b'{"name":"xe5xbcxa0xe4xb8x89","age":18}' type: <class 'bytes'>
结果bytes转str: {"name":"张三","age":18}
列表map转json: b'[{"name":"xe5xbcxa0xe4xb8x89","age":18},{"name":"xe6x9dx8exe5x9bx9b","age":33},{"name":"xe7x8ex8bxe4xbax94","age":20}]' type: <class 'bytes'>
结果bytes转str: [{"name":"张三","age":18},{"name":"李四","age":33},{"name":"王五","age":20}]
@注: 通过上面示例可以发现,序列化后的数据类型为
bytes
,需要通过x.decode('utf-8')转str
2.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转列表:[1, 2, 3, 4, 5, 6, 7, 8, 9] type:<class 'list'>
json转字典:{'name': '张三', 'age': 18} type:<class 'dict'>
json转字典列表:[{'name': '张三', 'age': 18}, {'name': '李四', 'age': 33}, {'name': '王五', 'age': 20}] type:<class 'list'>
2.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
2.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'>
2.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

原文始发于微信公众号(猿码记):Python常用库(四):json序列化和反序列
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/186160.html