Python 字典和 json 字符串相互转化方法
昨晚我下班回家在沙县小吃点了一份拌面,等面的功夫刷手机,有个朋友在群里问:Python 里面字典和 JSON 字符串怎么互转?一瞬间我想起好多新手都踩过坑,比如存配置、调接口、写日志的时候,结果转出来的数据不是想要的样子,要么报错要么乱码。正好借这个话题聊聊,顺便写一篇完整点的文章,大家以后遇到类似问题就不用再到处搜答案了。
字典和 JSON 的关系
说白了,Python 的字典 dict 和 JSON 对象其实挺像的,都是 key-value 的形式。但是别忘了,JSON 是字符串格式,本质就是文本,而字典是内存里的数据结构。举个例子:
data = {"name": "小李", "age": 25, "skills": ["Python", "Go"]}
这是一个字典,而转成 JSON 后长这样:
{"name": "小李", "age": 25, "skills": ["Python", "Go"]}
看起来差不多,但一个是字符串,一个是结构体。理解这一点,你才能明白为什么有时候传输数据必须转成 JSON。
dict 转 JSON 字符串
最常用的库是 json,Python 标准库自带,不用额外安装。
import jsondata = {"user": "张三", "score": 88}
json_str = json.dumps(data, ensure_ascii=False) # 中文不转义
print(json_str) # {"user": "张三", "score": 88}
注意:如果不加 ensure_ascii=False,默认会把中文变成 Unicode 编码,看着很别扭。
print(json.dumps(data))
# {"user": "\u5f20\u4e09", "score": 88}
JSON 字符串转 dict
有了字符串就要反序列化回来:
json_str = '{"user": "张三", "score": 88}'
data = json.loads(json_str)
print(data["user"]) # 张三
这就是常见的两步:dumps 和 loads。记住名字就行,dump 是“倒出来”,load 是“装进去”。
文件场景下的转换
有时候你要把数据写到文件里,这时候用 dump 和 load(注意没 s):
# 写入文件
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False)# 读取文件
with open("data.json", "r", encoding="utf-8") as f:
data_from_file = json.load(f)
这在做配置存储的时候非常方便,比如你写个小爬虫,把爬下来的内容存成 JSON 文件,下次直接读出来用。
常见坑
有些值不能直接转,比如 datetime 或者自定义对象:
from datetime import datetimedata = {"time": datetime.now()}
print(json.dumps(data)) # TypeError: Object of type datetime is not JSON serializable
这种情况需要自定义序列化方法:
defhandler(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError("Type not serializable")print(json.dumps(data, default=handler))
或者用第三方库 simplejson,支持更丰富。
字典嵌套和格式化输出
平时调试的时候,打印 JSON 一大坨不好看,可以加 indent:
data = {"user": "李四", "scores": {"math": 90, "english": 85}}
print(json.dumps(data, indent=4, ensure_ascii=False))
结果会缩进,结构一目了然。这在日志里也挺有用,查问题的时候不至于眼花。
和 API 打交道
比如调用一个 HTTP 接口,返回的内容一般就是 JSON 字符串。常见写法:
import requestsresp = requests.get("https://api.github.com")
data = resp.json()
print(type(data)) # <class 'dict'>
requests 已经帮你做好了 json.loads,直接拿字典用就行。反过来,如果你要 POST 数据,也要把字典转成 JSON:
payload = {"msg": "hello"}
resp = requests.post("http://example.com/api", json=payload)
这里 requests 内部会自动 dumps。
字典转 JSON 里的细节
顺带提一个小技巧,字典里的 key 必须是字符串,如果你写了个整数 key:
data = {1: "a", 2: "b"}
print(json.dumps(data))
# {"1": "a", "2": "b"}
会被自动转成字符串。要是不注意,拿回来可能对不上。
很多人会混淆 JSON 和 Python 的 pickle。简单说,pickle 可以序列化任何 Python 对象,但它是二进制,跨语言不通用。而 JSON 是纯文本,几乎所有语言都支持,所以更适合在服务之间传输。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领