欢迎!如果你想学习如何在Python中和JSON文件交互,那么本文适合你。
你将学习:
json
模块loads()
和dumps()
load()
读取JSON文件dump()
将JSON字符串写入文件准备好了吗?让我们开始吧!✨
JSON格式的产生最初是受到JavaScript(一种用于Web开发的编程语言)语法的启发,但在那之后,它成为一种独立于语言的数据格式,并且今天我们所使用的大多数编程语言都可以生成和读取JSON。
基本上,JSON是一种用于存储或表示数据的格式。它的常见用例包括Web开发和配置文件。
让我们看看原因:
manifest.json
的JSON文件,用于指定应用程序的名称、描述、当前版本以及其它属性和设置。既然已经知道了JSON的用途,那么让我们通过一个比萨饼订单数据的示例来看看它的基本结构:
{
'size': 'medium',
'price': 15.67,
'toppings': ['mushrooms', 'pepperoni', 'basil'],
'extra_cheese': false,
'delivery': true,
'client': {
'name': 'Jane Doe',
'phone': null,
'email': 'janedoe@email.com'
}
}
上面是示例的sample.json文件。
以下是JSON格式的主要特征:
{}
括起来的键-值对。'key': <value>
💡 提示:value
的内容必须用双引号括起来。
{
'size': 'medium', # Comma!
'price': 15.67
}
💡 提示: 我们通常使用不同级别的缩进来格式化JSON,以使数据更易于阅读。在本文中,你将学习如何使用Python自动添加缩进。
JSON文件具有特定规则,其用于确定哪些数据类型是有效的键和值。
true
/false
)、null
或JSON对象。根据Python文档:
JSON的键/值对中的键始终是
str
类型。当字典转换为JSON时,字典中的所有键都被强制转换为字符串。
根据Google JSON Style Guide:
orders
而不是order
。JSON和字典从显示形式来看可能非常相似,但它们有很大的不同。让我们看看它们是如何“连接(译者:这里意思应该是它们之间的关系)”,以及如何相互补充,来使得Python成为处理JSON文件的强大工具。
JSON是用于表示和存储数据的文件格式,而Python字典是Pythons程序运行时保存在内存中的实际数据结构(对象)。
当我们在Python中处理JSON文件时,我们不能直接读取数据并在程序中使用它,这是因为整个文件被表示为单个字符串,我们无法单独访问键值对。
除非······
我们使用JSON文件的键-值对创建一个Python字典,这样我们就可以在程序中使用它来读取、使用和修改(如果需要的话)数据。
这是JSON和Python字典之间的“联系”:JSON是数据的字符串表示,字典是程序运行时在内存中创建的实际数据结构。(译者注:字典转换为JSON叫序列化,反之为反序列化)
很好,既然你已经对JSON有足够多的了解,那么让我们开始深入了解实际情况中如何在Python里使用JSON的。
幸运的是,Python自带一个名为json
的内置模块,安装Python时会自动安装该模块,这个模块包含一些帮助处理JSON文件和字符串的功能。
我们将在接下来的示例中使用此模块。
要在程序中使用json
,只需在文件顶部写一个导入语句。(译者注:实际上只要在使用它之前导入就行)
就像这样:
通过此行就可以使用模块中定义的函数,我们将在示例中调用其中几个方法。
💡 提示: 如果写了上面的导入语句,则需要使用下面的语法来调用在json
模块中定义的函数:
为了说明json
模块中最重要的一些函数是如何工作的,我们将使用JSON格式的多行字符串。
特别地,这个字符串只是一个普通的遵循JSON格式的多行Python字符串,我们将在示例中使用它。
data_JSON = '''
{
'size': 'Medium',
'price': 15.67,
'toppings': ['Mushrooms', 'Extra Cheese', 'Pepperoni', 'Basil'],
'client': {
'name': 'Jane Doe',
'phone': '455-344-234',
'email': 'janedoe@email.com'
}
}
'''
JSON字符串
data_JSON
。💡 提示:Python Style Guide建议三重引号字符串使用双引号。
我们将使用此JSON格式的字符串来创建一个可以访问、使用和修改的Python字典。
为此,我们将使用json
模块的loads()
函数,并将字符串作为参数传递进去。
这是基本语法:
这是代码:
# 导入模块
import json
# JSON格式的字符串
data_JSON = '''
{
'size': 'Medium',
'price': 15.67,
'toppings': ['Mushrooms', 'Extra Cheese', 'Pepperoni', 'Basil'],
'client': {
'name': 'Jane Doe',
'phone': '455-344-234',
'email': 'janedoe@email.com'
}
}
'''
# 将JSON字符串转换为字典
data_dict = json.loads(data_JSON)
注意这行:
data_dict = json.loads(data_JSON)
json.loads(data_json)
使用JSON字符串的键-值对创建一个新字典,并返回这个字典。data_dict
。太棒了! 如果我们打印这个字典,会看到以下输出:
{'size': 'Medium', 'price': 15.67, 'toppings': ['Mushrooms', 'Extra Cheese', 'Pepperoni', 'Basil'], 'client': {'name': 'Jane Doe', 'phone': '455-344-234', 'email': 'janedoe@email.com'}}
字典中已填充了JSON字符串的数据,每个键值对都被成功添加到字典里。
现在让我们尝试使用与访问常规Python字典相同的语法,来访问键-值对的值,看看会发生什么:
print(data_dict['size'])
print(data_dict['price'])
print(data_dict['toppings'])
print(data_dict['client'])
输出是:
Medium
15.67
['Mushrooms', 'Extra Cheese', 'Pepperoni', 'Basil']
{'name': 'Jane Doe', 'phone': '455-344-234', 'email': 'janedoe@email.com'}
每个键都可以用来访问其对应的值,正如我们所期望的那样。
💡 提示: 我们可以像使用任何其它Python字典一样来使用此字典。例如,我们可以调用字典的方法,添加、更新和删除键-值对,以及其它等等操作,我们甚至可以在for循环中使用它。
当使用loads()
从JSON字符串来创建Python字典时,你会注意到一些值将被转换为Python中对应的值和数据类型。
Python文档上的这个json
模块表格总结了JSON数据类型和Python数据类型的对应关系:
这是官方json模块文档中的表格
💡 提示:当我们处理JSON文件时,转换表同样也适用。
现在你知道了如何用JSON格式的字符串创建Python字典。
但有时我们可能需要做相反的事情,即用对象(例如字典)创建JSON格式的字符串,以便打印、显示、存储,或者将其作为字符串使用。
为此,我们可以使用json
模块的dumps
函数,该函数要求将(要转换的)对象作为参数传递:
💡 提示: 此函数将返回一个字符串。
这是一个例子,我们将Python字典client
转换为JSON格式的字符串,并将其赋值给变量:
# Python Dictionary
client = {
'name': 'Nora',
'age': 56,
'id': '45355',
'eye_color': 'green',
'wears_glasses': False
}
# 获得一个JSON格式的字符串
client_JSON = json.dumps(client)
注意这行:
client_JSON = json.dumps(client)
json.dumps(client)
创建并返回一个包含字典中所有键-值对的JSON格式的字符串。client_JSON
变量。如果我们打印这个字符串,会看到如下输出:
{'name': 'Nora', 'age': 56, 'id': '45355', 'eye_color': 'green', 'wears_glasses': false}
💡 提示: 请注意,最后一个值(false
)已更改。在Python字典中,此值为False
,但在JSON中等效值为false
,这有助于我们确认原始字典现在确实已经表示为JSON格式的字符串。
如果我们检查此变量(client_JSON
)的数据类型,我们会看到:
<class 'str'>
所以这个函数的返回值确实是一个字符串。
当我们将字典转换为JSON字符串时,也会发生类型转换过程。来自Python文档的这张表显示了二者相对应的值:
表格来自官方json模块文档。
如果我们使用dumps
函数打印上一示例中得到的字符串,我们会看到:
{'name': 'Nora', 'age': 56, 'id': '45355', 'eye_color': 'green', 'wears_glasses': false}
但是这样可读性不是很高,对吧?
我们可以通过添加缩进来提高JSON字符串的可读性。
我们只需传递第二个参数来指定要用于JSON字符串缩进的空格数,(dumps
函数)就会自动执行此操作:
💡 提示: 第二个参数必须是非负整数(表示空格数)或字符串,如果indent
是一个字符串(例如'\t'
),则用该字符串缩进每个级别(帮助文档)。
现在,如果我们使用第二个参数来调用dumps
:
client_JSON = json.dumps(client, indent=4)
打印client_JSON
的结果是:
{
'name': 'Nora',
'age': 56,
'id': '45355',
'eye_color': 'green',
'wears_glasses': false
}
这很棒,对吧?现在我们的字符串格式很好看,这对我们处理存储人类可读格式的数据的文件来说将非常有用。
如果有需要,还可以按字母顺序对键进行排序,只需写入参数sort_keys
并传递值True
:
💡 提示: 如果不传递值,sort_keys
默认为False
。
例如:
client_JSON = json.dumps(client, sort_keys=True)
将会返回键按字母顺序排序的JSON字符串:
{'age': 56, 'eye_color': 'green', 'id': '45355', 'name': 'Nora', 'wears_glasses': false}
要生成(键)按字母顺序和有缩进的JSON字符串,只需要传递两个参数:
在这个例子中,输出是:
{
'age': 56,
'eye_color': 'green',
'id': '45355',
'name': 'Nora',
'wears_glasses': false
}
💡 提示: 可以按任何顺序(相对于彼此)传递这两个参数,但(要进行转换的)对象必须是第一个参数。
太棒了,现在你已经知道如何使用JSON字符串,那就让我们看看如何在Python程序中处理JSON文件。
JSON通常用于将数据存储在文件中,因此Python为我们提供了在程序中读取这些类型的文件、处理文件的数据以及编写新数据所需的工具。
💡 提示:JSON文件有一个.json
扩展名:
来看看如何在Python中处理.json
文件。
假设我们创建了一个 orders.json
文件,文件中有披萨店两个订单的数据:
{
'orders': [
{
'size': 'medium',
'price': 15.67,
'toppings': ['mushrooms', 'pepperoni', 'basil'],
'extra_cheese': false,
'delivery': true,
'client': {
'name': 'Jane Doe',
'phone': null,
'email': 'janedoe@email.com'
}
},
{
'size': 'small',
'price': 6.54,
'toppings': null,
'extra_cheese': true,
'delivery': false,
'client': {
'name': 'Foo Jones',
'phone': '556-342-452',
'email': null
}
}
]
}
orders.json
请花点时间分析此JSON文件的结构。
以下是一些提示:
'orders'
的值是一个JSON对象数组(这个数组在Python中表示列表),(数组里)每个JSON对象都保存了披萨订单的数据。如果我们想在Python中读取此文件,只需要使用with
语句:
💡 提示: 在上面的语法中,我们可以为file
(绿色框)指定任何名称,这是一个我们可以在with
语句中用来引用文件对象的变量。
此语法中的关键代码行是:
data = json.load(file)
json.load(file)
创建并返回一个新的包含JSON文件中键-值对的Python字典。data
变量。💡 提示: 请注意,我们使用的是load()
而不是loads()
,这是json
模块中的不同函数。你将在本文的末尾了解更多它们的差异。
一旦我们将JSON文件的内容作为字典存储在data
变量中,我们就可以使用它做想要做的任何事情。
例如,如果我们执行:
print(len(data['orders']))
输出为2
,因为主键orders
的值是一个包含两个元素的列表。
我们还可以使用键访问其对应的值,即处理JSON文件时通常要做的事情。
例如,要访问第一个订单的toppings,我们执行:
data['orders'][0]['toppings']
'orders'
0
)'toppings'
对应的值你可以在图表中以图形方式看到此“路径”:
如果我们打印这个值,输出是:
['mushrooms', 'pepperoni', 'basil']
这正是我们所期望的。你只需要通过使用必要的键和索引来“深入”了解字典的结构(可以使用原始JSON文件或字符串作为视觉参考),就可以访问、修改或删除任何值。
💡 提示: 请记住,我们正在使用新创建的字典,对此字典所做的更改不会影响原JSON文件。要更新文件的内容,需要写入文件中。
让我们看看如何写一个JSON文件。
第一行的with
语句(和读JSON文件)非常相似,唯一的改变是需要以'w'
(即写入)模式打开文件,这样才能修改文件。
💡 提示: 如果当前工作目录(文件夹)中文件不存在,则会自动创建该文件。如果文件存在,通过使用'w'
模式,我们将替换文件的全部内容。
在with
语句中,有两种写入JSON文件的方法:
dump
dumps
让我们详细看看。
第一种方法:dump
这是一个有两个参数的函数:
如果披萨店想从JSON文件中删除客户的数据,并创建一个新版本的orders_new.json
文件。
我们可以通过以下代码完成此操作:
# 打开orders.json文件
with open('orders.json') as file:
# 加载它的内容并创建一个新字典
data = json.load(file)
# 在每个order中删除'client'键-值对
for order in data['orders']:
del order['client']
# 打开(或者创建)一个orders_new.json文件
# 保存新版本的数据
with open('orders_new.json', 'w') as file:
json.dump(data, file)
这是 orders.json
中数据的原始版本,请注意里面存在'client'
键-值对。
{
'orders': [
{
'size': 'medium',
'price': 15.67,
'toppings': ['mushrooms', 'pepperoni', 'basil'],
'extra_cheese': false,
'delivery': true,
'client': {
'name': 'Jane Doe',
'phone': null,
'email': 'janedoe@email.com'
}
},
{
'size': 'small',
'price': 6.54,
'toppings': null,
'extra_cheese': true,
'delivery': false,
'client': {
'name': 'Foo Jones',
'phone': '556-342-452',
'email': null
}
}
]
}
orders.json
这是orders_new.json
文件里的新版本数据:
{'orders': [{'size': 'medium', 'price': 15.67, 'toppings': ['mushrooms', 'pepperoni', 'basil'], 'extra_cheese': false, 'delivery': true}, {'size': 'small', 'price': 6.54, 'toppings': null, 'extra_cheese': true, 'delivery': false}]}
orders_new.json
如果仔细分析,你会发现'clients'
键-值对从所有订单中被删除。
然而,这个文件中缺少了一些东西,对吗?
请花点时间思考一下…可能是什么?
当然是缩进!
该文件实际上看起来不像JSON文件,但我们可以通过将参数indentation=4
传递给dump()
来轻松解决这个问题。
现在文件内容如下所示:
{
'orders': [
{
'size': 'medium',
'price': 15.67,
'toppings': [
'mushrooms',
'pepperoni',
'basil'
],
'extra_cheese': false,
'delivery': true
},
{
'size': 'small',
'price': 6.54,
'toppings': null,
'extra_cheese': true,
'delivery': false
}
]
}
多么大的变化啊!这正是我们期望的JSON文件的样子。
现在你已经知道如何使用load()
和dump
来读取和写入JSON文件,就让我们看看这两个函数和用来处理JSON字符串的函数之间的区别。
这个表格总结了这两个函数之间的主要区别:
💡 提示: 将loads()
视为'load string',这有助于记住函数处理的目标。
这是一个总结了两个函数之间主要差异的表格:
💡 提示: 将dumps()
视为'dump string',这有助于记住函数处理的目标。
最后,使用JSON需要了解两个重要术语:
.json
扩展名。我真的希望你喜欢我的文章,并觉得它很有帮助。
Happy coding!
原文链接:https://www.freecodecamp.org/news/python-read-json-file-how-to-load-json-from-a-file-and-parse-dumps/
作者:Estefania Cassingena Navone
联系客服