与数据打交道是使用Python作为一种编程语言的全部意义。JSON 可能是最常见的数据格式,我们现在就来看看如何使用 Python 处理 JSON。Python 可以处理来自一系列可能的数据源的 JSON,如文件、Web APIs 或输出 JSON 的第三方模块。Python有一个用于处理JSON的内置模块,它是Python标准库的一部分。
Python JSON解析函数
- obj =
load(文件) - obj =
loads(字符串)
Python JSON 序列化函数
dump(obj, file)- str =
dumps(obj)
将Python数据序列化为JSON
Python将数据转换为JSON,如下表所示。Python字典对象被转换为JSON对象。Lists和Tuples被转换为数组。Python字符串被转换为JavaScript字符串。Python中由整数和浮点数衍生的数字类型被解析为数字。布尔值True和False被转换为JavaScript中的对应值,Python中的None值被转换为JSON中的null。
| Python对象 | JSON表示法 |
| dict | 对象 |
| 列表,元组 | 数组 |
| str | 字符串 |
| int, long, float, Enums | 数字 |
| 真实 | 真 |
| 假的 | 假 |
| 无 | 无 |
将JSON解析到Python中
将JSON解析成Python与上面提到的序列化步骤几乎是相反的。唯一的例外是处理列表和图元。其原因是Python中的列表和图元在JSON中被编码为数组。这意味着当你把列表解析回 Python 时,没有办法知道它最初是一个列表还是一个元组。你可以把一个 Python 对象,序列化为 JSON,再解析回 Python,然后得到一个与你开始时不同的对象。启示是,当把 JSON 解析成 Python 时,你永远不会在 Python 对象中得到一个元组,它总是一个列表。
| JSON 数据 | Python 对象 |
| 对象 | dict |
| 数组 | 列表 |
| 字符串 | str |
| 整数编号 | int |
| 浮点数 | float |
| true, false | 真,假 |
| 空 | 无 |
json.load() 解析示例
这里有一些Python代码来展示使用json.load()方法。要使用 loads() ,首先需要将 json 导入 Python 文件,这很容易。你所需要做的就是在文件的开头输入import json。在代码中,有一个变量名为 **jsonstring**的变量,它有一个分配给它的JSON格式的字符串。这个数据结构代表了你最喜欢的墨西哥卷饼店的一个虚构的订单。这允许我们使用json.load(jsonstring)读取JSON数据,将结果存储到 **data**变量中。该变量 **jsonstring*在使用load()函数之前是<class 'str'>*类型。结果存储在 **data*的类型是<class 'dict'>。*一旦我们有了 Python 字典中的数据,你就可以看到在内容上进行循环是多么的容易。
import json
jsonstring = '''{
"burrito" : "Steak",
"double-meat" : true,
"toppings" : [
"Black Beans",
"Lettuce",
"Salsa",
"Guacamole"
],
"price" : 9.17
}'''
data = json.loads(jsonstring)
print('Order: ' + data['burrito'])
if (data['double-meat']):
print('With Double Meat')
for topping in data['toppings']:
print('Topping: ' + topping)
Order: Steak
With Double Meat
Topping: Black Beans
Topping: Lettuce
Topping: Salsa
Topping: Guacamole
json.dumps() 序列化实例
现在我们可以很容易地将一个 Python 对象序列化为 JSON 表示。在下面的代码中,有一个 **pythondict**变量,它持有关于我们的Burrito订单的所有信息。这个Python字典可以用*json.dumps()*函数转换为JSON字符串。我们把要转换的数据作为第一个参数传给该函数,把要使用的缩进空间的数量作为命名的第二个参数。该操作的结果被存储在 **jsonstring**变量中。当我们将该变量打印出来时,我们看到一个漂亮的JSON字符串作为输出。所以现在我们看到了如何使用Python来解析和序列化JSON数据。
import json
pythondict = {
'burrito': 'Steak',
'double-meat': True,
'toppings': ['Black Beans',
'Lettuce',
'Salsa',
'Guacamole'
],
'price': 9.17
}
jsonstring = json.dumps(pythondict, indent=4)
print('-------- JSON String Data --------')
print(jsonstring)
-------- JSON String Data --------
{
"burrito": "Steak",
"double-meat": true,
"toppings": [
"Black Beans",
"Lettuce",
"Salsa",
"Guacamole"
],
"price": 9.17
}
用JSONDecodeError处理JSON错误
在Python中解析和序列化JSON时,有可能遇到错误。为了处理这些情况,我们可以使用JSONDecodeError类,它是JSON模块本身的一部分。让我们重新审视到目前为止的一个例子,把JSON解析包在一个try/except块中。我们使用JSONDecodeError来在出错时发出自定义的错误信息。代码中突出显示了缺少逗号的地方,运行代码的结果显示这个错误被捕获和处理。
import json
from json import JSONDecodeError
jsonstring = '''{
"burrito" : "Steak",
"double-meat" : true,
"toppings" : [
"Black Beans",
"Lettuce"
"Salsa",
"Guacamole"
],
"price" : 9.17
}'''
try:
data = json.loads(jsonstring)
print('Order: ' + data['burrito'])
if (data['double-meat']):
print('With Double Meat')
for topping in data['toppings']:
print('Topping: ' + topping)
except JSONDecodeError as error:
print('Hold on now, there was a JSON Decoding erroror:')
print(error.msg)
print(error.lineno, error.colno)
Hold on now, there was a JSON Decoding erroror:
Expecting ',' delimiter
7 13
现在我们在JSON中出现了一个不同的错误。
import json
from json import JSONDecodeError
jsonstring = '''{
"burrito" : "Steak",
"double-meat" : true,
"toppings" : [
"Black Beans",
"Lettuce",
"Salsa",
"Guacamole
],
"price" : 9.17
}'''
try:
data = json.loads(jsonstring)
print('Order: ' + data['burrito'])
if (data['double-meat']):
print('With Double Meat')
for topping in data['toppings']:
print('Topping: ' + topping)
except JSONDecodeError as error:
print('Hold on now, there was a JSON Decoding erroror:')
print(error.msg)
print(error.lineno, error.colno)
Hold on now, there was a JSON Decoding erroror:
Invalid control character at
8 23
在API中处理JSON
我们可以再次使用熟悉的httpbin.org网站来测试使用[Requests库]以及一些JSON解析和序列化。检索JSON文本并将其解析为本地字典的模式在Python中很常见,Requests库将自动检测从请求中返回的内容是否是JSON,并为你解析。在下面的代码中,你可以看到我们使用*requests.get(url)*向 httpbin.org/json 发出一个 GET 请求。该端点提供了这个输出。

这个 **.json()**函数是一个方便的函数,允许开发者快速访问JSON数据。
import json, requests
url = 'http://httpbin.org/json'
result = requests.get(url)
pythondict = result.json()
print(json.dumps(pythondict, indent=4))
print(list(pythondict.keys()))
print(pythondict['slideshow']['title'])
slides = len(pythondict['slideshow']['slides'])
print(f'There are {slides} slides')
{
"slideshow": {
"author": "Yours Truly",
"date": "date of publication",
"slides": [
{
"title": "Wake up to WonderWidgets!",
"type": "all"
},
{
"items": [
"Why <em>WonderWidgets</em> are great",
"Who <em>buys</em> WonderWidgets"
],
"title": "Overview",
"type": "all"
}
],
"title": "Sample Slide Show"
}
}
['slideshow']
Sample Slide Show
There are 2 slides