Python技术迷

Python字典与JSON字符串如何互转

今天我们来聊一个常见的问题:Python字典与JSON字符串如何互转。

作为开发中不可避免的操作,字典和JSON字符串的转换已经成了“日常需求”,几乎所有开发者都需要处理这种情况。今天就带大家一起深挖一下这个问题。别担心,技术细节我会尽量讲得清晰、简单,配合代码示例,一点也不会枯燥。

字典和JSON到底是什么?

首先,咱们得简单理解一下字典(dict)和JSON(JavaScript Object Notation)这两个东西。

  • 字典(dict):在Python中,字典就是一种无序的数据结构,它以键-值对的形式存储数据。我们可以通过键来快速查找对应的值。比如:{"name": "Tom", "age": 25},这里 "name" 是键,"Tom" 是值。

  • JSON:JSON本质上是一个轻量级的数据交换格式,用于存储和传输数据。它的结构类似于Python中的字典,但其实它并不是Python中的原生数据结构。JSON的语法有点像字典,但它是一个纯文本格式,通常用于服务器和客户端之间的通信。

你可以把JSON看作一种标准化的字符串格式,用来在不同语言之间交换数据。Python有一个强大的模块json,可以帮助我们在字典和JSON字符串之间进行转换。

为什么需要转换?

在实际的应用中,我们常常需要和外部API或者数据库进行数据交换,这时候就需要用到JSON格式。因为大多数Web API,特别是RESTful接口,都返回JSON格式的数据。反过来,如果你需要将Python中的数据传输给外部系统,JSON格式也是常见的选择。

而Python中原生的数据结构,尤其是字典,是非常方便的,但它并不能直接传输或者存储到外部系统中,所以就需要通过转换,才能适应JSON格式的需求。

好,接下来我们就来看看如何在Python中进行字典和JSON的转换。

从字典转换到JSON

我们可以利用Python内置的json模块来将字典转换成JSON字符串。这里有一个小例子:

import json

# 创建一个字典
data = {
    "name": "Tom",
    "age": 25,
    "city": "New York"
}

# 将字典转换为JSON字符串
json_data = json.dumps(data)

print(json_data)

运行结果:

{"name": "Tom", "age": 25, "city": "New York"}

解释

  • json.dumps():这个方法可以把Python字典对象转换为JSON格式的字符串。需要注意的是,返回的是一个字符串,而不是字典。
  • json_data 就是我们得到的JSON格式字符串,格式上类似于字典,但它是一个文本格式,方便传输。

从JSON字符串转换到字典

有时候我们会接收到JSON格式的字符串,比如从API接口中拿到的响应内容。这个时候我们需要将JSON字符串转回字典格式,以便于后续处理。可以通过json.loads()方法来实现:

import json

# 一个JSON字符串
json_str = '{"name": "Tom", "age": 25, "city": "New York"}'

# 将JSON字符串转换为字典
data = json.loads(json_str)

print(data)

运行结果:

{'name': 'Tom', 'age': 25, 'city': 'New York'}

解释

  • json.loads():这个方法接受一个JSON格式的字符串作为输入,并将其转换为Python字典对象。这样我们就可以像操作普通字典一样操作这个数据了。

进阶应用:自定义JSON序列化和反序列化

有时候,字典中的某些值并不是标准类型(如自定义对象),这时候我们就需要自定义序列化和反序列化过程。举个例子,如果字典中的值是一个日期对象,Python原生的json.dumps()方法就不能直接处理。

自定义JSON序列化

假设我们有一个日期对象,我们需要把它转换成字符串格式。

import json
from datetime import datetime

# 自定义的字典
data = {
    "name": "Tom",
    "age": 25,
    "date_of_birth": datetime(1997, 5, 12)
}

# 自定义序列化方法
def date_serializer(obj):
    if isinstance(obj, datetime):
        return obj.strftime('%Y-%m-%d')
    raise TypeError("Type not serializable")

# 将字典转换为JSON字符串,使用自定义的序列化方法
json_data = json.dumps(data, default=date_serializer)

print(json_data)

运行结果:

{"name": "Tom", "age": 25, "date_of_birth": "1997-05-12"}

自定义JSON反序列化

同样地,如果从JSON字符串中获取到一个日期字符串,我们也可以自定义反序列化规则,把它转换回datetime对象。

import json
from datetime import datetime

# 一个包含日期字符串的JSON字符串
json_str = '{"name": "Tom", "age": 25, "date_of_birth": "1997-05-12"}'

# 自定义反序列化方法
def date_parser(dct):
    if 'date_of_birth' in dct:
        dct['date_of_birth'] = datetime.strptime(dct['date_of_birth'], '%Y-%m-%d')
    return dct

# 将JSON字符串转换为字典,使用自定义的反序列化方法
data = json.loads(json_str, object_hook=date_parser)

print(data)

运行结果:

{'name': 'Tom', 'age': 25, 'date_of_birth': datetime.datetime(1997, 5, 12, 0, 0)}

常见问题:字典转换为JSON失败

有时候,我们会遇到TypeError: Object of type XXX is not JSON serializable这样的错误。通常是因为字典中有些对象不能直接转换成JSON格式。比如,Python中的set集合类型、datetime对象等都不支持直接转换为JSON。

此时,最好的方法就是使用自定义的序列化方法,把这些特殊类型转化为JSON支持的类型。

总结

字典与JSON字符串之间的转换是非常基础但又必不可少的技能。通过json.dumps()和json.loads(),我们可以轻松实现它们之间的转换。如果遇到特殊类型,还可以通过自定义序列化和反序列化方法来确保它们能顺利转换。

这在实际开发中常常会用到,尤其是在做Web开发时,与前端的沟通和API接口的交互时,JSON几乎是不可避免的“桥梁”。记得遇到复杂数据时,别忘了自定义序列化和反序列化规则,否则很容易栽跟头。

不过说到这里,给大家一个小小的提醒:每次处理JSON时,最好都先检查下你要转的对象是不是基本类型(字典、列表、字符串、数字、布尔值),如果不是,记得“做功课”自定义一下序列化方法。到时出错你就知道是为什么啦。

对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
🔥虎哥私藏精品 热门推荐🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。

资料包含了《IDEA视频教程》、《最全python面试题库》、《最全项目实战源码及视频》及《毕业设计系统源码》,总量高达650GB,全部免费领取。