Python json 类介绍

json

json 模块在 Python 中用于处理 JSON 数据的编码和解码

dumps()

将 Python 对象转换为 JSON 数据的字符串

1
2
3
json.dumps(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw)

默认情况下, json.dumps() 可以处理的 Python 对象及其属性值类型必须为 dict, list, tuple, str, float 或者 int。这些类型与JSON的数据转换关系如下表:

PythonJSON
dictobject
list, tuplearray
strstring
int, float, longnumber
Truetrue
Falsefalse
Nonenull
1
2
3
4
5
6
7
8
9
10
11
import json

data = {
'status': True,
'extra': None,
'name': 'a',
'id': 1
}

# {"status": true, "extra": null, "name": "a", "id": 1}
print(json.dumps(data))
  • skipkeys

    JSON 规范中只能采用字符串作为键名,但在 Python 中只要是可哈希(hashable)的对象和数据都可以做为 Dictionary 对象的键。json.dumps() 会对这个规则进行检查,且键名允许的范围有所扩大, str、int、float、bool 和 None 类型的数据都可以做为键名,不过当键名非 str 的情况时, 键名会转换为对应的 str 值;但当出现其他类型的键名时, 默认出抛出异常。skipkeys 参数可以改变这种行为;skipkeys 设置为 True 时, 遇到非法的键名类型会跳过且不会抛出异常。

    1
    2
    3
    4
    5
    6
    7
    8
    ## skipkeys 参数
    data = { (1, 2): 123}

    # {}
    print(json.dumps(data, skipkeys=True))

    # TypeError: keys must be str, int, float, bool or None, not tuple
    print(json.dumps(data))
  • ensure_ascii

    ensure_ascii 参数用来控制生成的 JSON 字符串的编码;其默认值为 True, 会将所有的非 ASCII 码字条进行转义;如果设为 False,表示不希望自动进行转义,则会保持原有编码(限 UTF-8)。

    1
    2
    3
    4
    5
    6
    7
    8
    ## ensure_ascii 参数
    data = { '姓名': 'a', '年龄': 'b' }

    # {"\u59d3\u540d": "a", "\u5e74\u9f84": "b"}
    print(json.dumps(data))

    # {"姓名": "a", "年龄": "b"}
    print(json.dumps(data, ensure_ascii=False))
  • check_circular

    json.dumps() 会检查 Python 对象中是否有循环引用, 如果发现了循环引用, 则抛出异常;可以将参数 check_circular 设置为 False,关闭循环引用。

    1
    2
    3
    4
    5
    6
    7
    8
    ## check_circular 参数
    data = {}
    data['self'] = data

    # ValueError: Circular reference detected
    print(json.dumps(data))

    print(json.dumps(data, check_circular=False))
  • allow_nan

    虽然 JSON 标准规范不支持 NaN、Infinity 和 -Infinity, 但是 json.dumps() 默认会将float(‘nan’)、float(‘inf’) 和 float(‘-inf’) 转换为常量 NaN, Infinity, 和-Infinity。

    但这些常量会导致生成的 JSON 字符串无法被其他 JSON 实现处理,为了避免这种情况,可以将 allow_nan 参数设为 False。allow_nan 为 False 时,json.dumps() 编码 Python 对象中的这些常量时会抛出异常。

    1
    2
    3
    4
    5
    6
    7
    8
    ## allow_nan 参数
    data = { 'nan': float('nan'), 'infinity': float('inf'), '-infinity': float('-inf') }

    # {"nan": NaN, "infinity": Infinity, "-infinity": -Infinity}
    print(json.dumps(data))

    # ValueError: Out of range float values are not JSON compliant
    print(json.dumps(data, allow_nan=False))
  • indent

    indent 参数可以控制 JSON 字符串的换行和缩进效果。

    indent 为 0 或负数时,只有换行效果;indent 大于 0 时,会以指定数量的空格为单位在对象层次间进行缩进。

    1
    2
    3
    4
    5
    6
    7
    8
    ## indent 参数
    data = { 'name': 'a', 'age': 18, 'score': { 'english': 80, 'math': 90 }}

    print(json.dumps(data))

    print(json.dumps(data, indent=0))

    print(json.dumps(data, indent=4))
  • separators

    separators 参数用来设置输出的分隔符(成员分隔符,键值分隔符),默认值受 indent 参数影响;当 indent 为 None 时, separators 默认值为 (‘, ‘, ‘: ‘);indent 不为 None 时, 其默认值则为 (‘,’, ‘:’)。

    1
    2
    3
    4
    5
    ## separators 参数
    data = { 'name': 'a', 'age': 18, 'score': { 'english': 80, 'math': 90 }}

    # {"name":"a","age":18,"score":{"english":80,"math":90}}
    print(json.dumps(data, separators=(',', ':')))
  • default

    默认情况下,json.dumps() 只能转换 Dictionary 类型对象,如果需要转换自定义对象,则需要设置 default 参数,该参数接收一个函数, 函数参数为需要转换的 Python 对象, 函数返回值为表示这个 Python 对象的 Dictionary 对象。

  • sort_keys

    sort_keys 参数决定是否需要按 JSON 字符串的健进行排序

    1
    2
    3
    4
    5
    6
    7
    8
    ## sort_keys 参数
    data = { 'name': 'a', 'age': 18, 'score': { 'english': 80, 'math': 90 }}

    # {"age": 18, "name": "a", "score": {"english": 80, "math": 90}}
    print(json.dumps(data, sort_keys=True))

    # {"name": "a", "age": 18, "score": {"english": 80, "math": 90}}
    print(json.dumps(data))

dump()

Python 不仅可以将 Python 对象转换为 JSON 字符串,还支持将转换后的字符串写入文件中。

1
2
3
dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw)
1
2
3
4
## json.dump()
data = { 'name': 'a', 'age': 18, 'score': { 'english': 80, 'math': 90 }}
with open('output.json', 'w') as fp:
json.dump(data, fp)

loads()

将包含了一个 JSON 数据的 str、bytes 或者 bytearray 对象, 转化为一个 Python Dictionary 对象。

1
2
loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

JSON和Python之间的数据转换对应关系如下表:

JSONPython
objectdict
arraylist
stringstr
number (int)int
number (real)float
trueTrue
falseFalse
nullNone
1
2
3
4
5
## json.loads()
data = { 'name': 'a', 'age': 18, 'score': { 'english': 80, 'math': 90 }}

# {'name': 'a', 'age': 18, 'score': {'english': 80, 'math': 90}}
print(json.loads(json.dumps(data)))

load()

将文件中的 JSON 数据转化为 Python Dictionary 对象。

1
2
3
4
## json.load()
with open('output.json', 'r') as f:
# {'name': 'a', 'age': 18, 'score': {'english': 80, 'math': 90}}
print(json.load(f))