详解Python中的json库
创始人
2024-11-10 19:08:37
0

目录

  • 1. json简介
  • 2. dumps/loads
  • 3. dump/load
  • 4. jsonl格式

1. json简介

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用于在不同应用程序之间传递数据。它是一种文本格式,易于阅读和编写,同时也易于解析和生成。JSON最初是由Douglas Crockford于2001年提出的,它基于JavaScript对象字面量语法,但已经成为一种独立于编程语言的数据格式。

乍一看json对象和python中的字典长得差不多,但前者是一种数据格式,而后者是一种数据结构。

具体来讲,json对象由一个大括号 {} 组成,大括号里保存的是若干个key-value对,其中key必须是字符串,且必须由双引号括起来(python的字典可以是单引号)。value可以是字符串,数值(整数/浮点数),布尔值,null,数组,json对象。key和value使用冒号 : 进行分隔,每个key-value对使用逗号 , 进行分隔。

📝 JSON是JavaScript对象字面量语法的一个子集。这意味着所有的JSON字符串在格式上都符合JavaScript对象字面量的语法规则,但并非所有JavaScript对象字面量的写法都是合法的JSON格式。

json对象通常存储在以 .json 为扩展名的文本文件中,一个可能的例子:

{     "k1": "a",     "k2": 1,     "k3": 1.1,     "k4": true,     "k5": false,     "k6": null,     "k7": [         1,         1.1,         false,         "b"     ],     "k8": {         "c": 2,         "d": 3     } } 

以上列出了value所有可能的数据类型。当然,json文件中可以包含多个json对象,通常由一个大列表括起来,每个json对象间用逗号分隔:

[     {         "k1": 1,         "k2": 2     },     {         "k3": 3,         "k4": 4     } ] 

事实上,json文件能存储的有:

  • 单个简单值:例如数值,字符串,布尔值,null。
  • 单个数组:数组的内容可以是简单值,其他数组以及json对象。
  • 单个json对象:包含一系列key-value对。

📝 看起来只有三种,但展开后就是上面提到的六种:Number(int/float)StringBooleanNullArrayObject其中 Object 指的就是由 {} 括起来的一组无序的键值对。

对于数组和json对象,其中的最后一个元素后面不能有逗号

json 库是python的标准库,它主要有四个函数:dumpdumpsloadloads,接下来也只讲解这四个函数。

2. dumps/loads

dumps用于将一个python对象转化成json格式的字符串,其中python对象必须是json可序列化的,即上面提到的三种。dumps这一过程又被称为序列化。

不严谨地来讲,dumps的函数签名如下:

def dumps(obj: Union[None, int, float, str, bool, list, dict], *args) -> str:     pass 

一些示例:

print(json.dumps(None)) # null print(json.dumps(1)) # 1 print(json.dumps(3.3)) # 3.3 print(json.dumps("abc")) # "abc"  print(json.dumps([1, 2, 3, 4])) # [1, 2, 3, 4] print(json.dumps({"a": 1, "b": 2})) # {"a": 1, "b": 2} 

loads的作用与dumps相反,loads过程又被称为反序列化,即将一个json格式的字符串转化为相应的python对象。

不严谨地来讲,loads的函数签名如下:

def loads(s: str, *args) -> Union[None, int, float, str, bool, list, dict]:     pass 

📝 s 还可以是bytes或bytearray,这超出了本文的讨论范围。

一些示例:

print(json.loads("null")) # None print(json.loads("1")) # 1 print(json.loads("3.3")) # 3.3 print(json.loads("\"abc\"")) # abc  print(json.loads("[1, 2, 3, 4]")) # [1, 2, 3, 4] print(json.loads("{\"a\": 1, \"b\": 2}")) # {'a': 1, 'b': 2} 

在使用dumps时有一个小细节,如下:

print(json.dumps("abc你好")) # "abc\u4f60\u597d" 

默认情况下,所有非 ASCII 字符(即那些无法用标准 ASCII 表示的字符)都被转义为 Unicode 转义序列。这样做的目的是为了确保生成的 JSON 字符串是 ASCII 编码的,因为一些旧系统或处理 JSON 数据的应用程序可能不支持非 ASCII 字符。

如果要防止对非ASCII字符进行转义,可以设置 ensure_ascii = False,如下:

print(json.dumps("abc你好", ensure_ascii=False)) # "abc你好" 

3. dump/load

dump用于将一个python对象(需要是json可序列化的)保存到相应的json文件中,dump没有返回值。

with open('1.json', 'w') as f:     json.dump([1, 2, 3], f) 

load用于从一个json文件中读取并转化为相应的python对象:

with open('1.json') as f:     print(json.load(f)) # [1, 2, 3] 

4. jsonl格式

JSONL(JSON Lines)中的每一行都是一个json对象,如下:

{"name": "John", "age": 30, "city": "New York"} {"name": "Alice", "age": 25, "city": "Los Angeles"} {"name": "Bob", "age": 35, "city": "Chicago"} 

JSONL 更适合处理大型数据集,特别是日志文件和行格式数据。它可以逐行处理,而不需要一次性加载整个文件到内存中。这使得它在处理大型数据文件时更具效率。

使用json库对jsonl文件进行读写:

# 读取 with open('1.jsonl') as r:     for line in r:         print(json.loads(line))  # 写入 content = ...  # 预定义 with open('1.jsonl', 'w') as w:     for line in content:         w.write(json.dumps(line, ensure_ascii=False) + '\n') 

使用 jsonlines 库,我们可以更高效的处理jsonl文件:

import jsonlines  # 读取 with jsonlines.open('1.jsonl') as r:     for line in r:         print(type(line), line) #  {'name': 'John', 'age': 30, 'city': 'New York'} #  {'name': 'Alice', 'age': 25, 'city': 'Los Angeles'} #  {'name': 'Bob', 'age': 35, 'city': 'Chicago'}  # 写入 dic = {"a": 1, "b": 2}  with jsonlines.open('1.jsonl', 'w') as w:     w.write(dic)  # 会自动加换行符  # 写入多个 dic = [{"a": 1, "b": 2}, {"c": 3, "d": 4}]  with jsonlines.open('1.jsonl', 'w') as w:     w.write_all(dic) 

可以看到我们能够直接对 dict 对象进行操作,而不需要进行 dict <-> str 的转化。

📝 write() 有返回值,即当前行的字符总数(包括换行符)。write_all() 是所有行的字符总数。

注意,jsonlinesWriter 并没有 flush() 方法,如需立即写入文件,可以在创建上下文管理器的时候设置 flush=True,如下:

with jsonlines.open('1.jsonl', 'w', flush=True) as w:     w.write(line) 

相关内容

热门资讯

攻略教程!!竞技联盟透视插件德... 攻略教程!!竞技联盟透视插件德扑之星技巧(就是真的有挂)1)竞技联盟透视插件辅助挂:进一步探索竞技联...
技术分享!aapoker透明挂... 技术分享!aapoker透明挂微扑克脚本代写(透明黑科技)原来真的有挂(wpk教程);1、aapok...
分享认知!wpk有外挂线上德州... 分享认知!wpk有外挂线上德州后台可以操控吗(辅助)其实真的有挂(爆料教程)1、让任何用户在无需wp...
热门推荐!we辅助poker德... 热门推荐!we辅助poker德之星wpk微扑克真的有辅助插件吗(透视辅助)其实真的有挂(透明教程)1...
科技通报!德扑之星有猫腻微扑克... 科技通报!德扑之星有猫腻微扑克有没有挂(透视辅助)其实真的有挂(wepoke教程)1、下载好德扑之星...
实测交流!wepower辅助器... 实测交流!wepower辅助器wepoke辅助插件(辅助)原来真的有挂(解密教程)1、下载好wepo...
玩家必看秘籍!wepokeai... 玩家必看秘籍!wepokeai机器人扑克世界牌局设置(透视辅助)原来真的有挂(解密教程)1、操作简单...
玩家必看科普!wepoke a... 玩家必看科普!wepoke ai辅助aapoker安卓版辅助(辅助)原来真的有挂(攻略方法)1、we...
教程辅助!wepoke辅助德州... 教程辅助!wepoke辅助德州ai辅助代理(透视辅助)其实真的有挂(安装教程)1、德州ai辅助ai辅...
每日必看推荐!aapoker透... 每日必看推荐!aapoker透视辅助德扑之星隐藏功能(辅助挂)其实真的有挂(系统教程)1、游戏颠覆性...