如何使用 Python 处理 JSON

185 阅读5分钟

与数据打交道是使用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 请求。该端点提供了这个输出。
httpbin json endpoint

这个 **.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