Python 中的json模块dumps参数详解
1.什么是JSON维基百科中的定义: JSON(JavaScriptObjectNotation,JavaScript对象表示法)是一种由道格拉斯·克罗克福特构想和设计、轻量级的资料交换语言,该语言以易于让人阅读的文字为基础,用来传输由属性值或者序列性的值组成的数据对象。尽管JSON是JavaScript的一个子集,但JSON是独立于语言的文本格式,并且采用了类似于C语言家族的一些习惯。一个数据示
1.什么是JSON
维基百科中的定义: JSON(JavaScript Object Notation,JavaScript对象表示法)是一种由道格拉斯·克罗克福特构想和设计、轻量级的资料交换语言,该语言以易于让人阅读的文字为基础,用来传输由属性值或者序列性的值组成的数据对象。尽管JSON是JavaScript的一个子集,但JSON是独立于语言的文本格式,并且采用了类似于C语言家族的一些习惯。
一个数据示例:
{
"firstName": "Micheal",
"lastName": "Jordan",
"hobbies": ["running", "golfing", "singing"],
"age": 35,
"children": [
{
"firstName": "Marcus",
"age": 14
},
{
"firstName": "Jeffrey",
"age": 12
}
]
}
JSON 支持原始类型,如数字, 字符串,以及嵌套列表和对象。
JSON 的编码过程通常称为序列化。该术语是指将数据对象转换为一系列字节以通过网络存储或传输
2. Python中的json
2.1 序列化 json.dump 和 json.dumps
- dump 将数据写入文件
- dumps 将数据生成字符串, dump+str
代码示例
In [1]: import json
In [2]: json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
Out[2]: '["foo", {"bar": ["baz", null, 1.0, 2]}]'
将数据dump到文件
In [3]: with open('data.json', 'w') as f:
...: data = {'database': 'mongo'}
...: json.dump(data, f)
数据 {"database": "mongo"} 被写入到data.json文件中
2.2 反序列化 json.load 和 json.loads
- load 将文件中的JSON数据载入为对象
- loads 将序列化的json字符串, 载入为JSON对象
通过表格可以看到, 反序列化并不是对序列化表的完美逆向, 反序列化不能生成tuple类型的数据.
In [4]: data = ('amigo', 'branda', 'ariza')
In [5]: json.loads(json.dumps(data))
Out[5]: ['amigo', 'branda', 'ariza']
2.3 dumps的参数
dumps函数提供一些参数, 可以控制序列化过程中的行为.
参数 | 描述 | 默认值 |
skipkeys | 是否跳过无法被JSON序列化的key(包括str, int, float, bool, None) | False |
sort_keys | 是否对数据按照key进行排序 | False |
ensure_ascii | 输出保证将所有输入的非 ASCII 字符转义 | True |
allow_nan | 是否允许JSON规范外的float数据(nan, inf, -inf) | True |
default | 是一个函数, 当某个value无法被序列化时, 对其调用该函数 | None |
indent | 是一个正整数, 代表序列化后的缩进 | None |
separator | 是一个格式为 (item_separator, key_separator) 的元组, 默认取值为 (', ', ': ') | None |
check_circular | 是否检查循环引用 | True |
下面使用一些数据示例依次说明:
2.3.1 skipkeys
In [1]: import json
In [2]: def func():
...: print('fun')
In [3]: data = {func: 'value', 'key': 'data'}
In [4]: json.dumps(data)
---------------------------------------------------------------------------
TypeError: keys must be str, int, float, bool or None, not function
In [5]: json.dumps(data, skipkeys=True)
Out[5]: '{"key": "data"}'
字典数据 data 中的其中一个key是个函数func, 无法直接被JSON序列化, 所以对其执行json.dumps时, 报TypeError, 将skipkeys置为True, 序列化时跳过键值func, 序列化成功.
2.3.2 sort_keys
In [6]: data = {'c': 3, 'b': 2, 'a': 1}
In [7]: json.dumps(data)
Out[7]: '{"c": 3, "b": 2, "a": 1}'
In [8]: json.dumps(data, sort_keys=True)
Out[8]: '{"a": 1, "b": 2, "c": 3}'
指定sort_keys=True之后, 序列化后的数据按照key值[a, b, c]进行排序
2.3.3 ensure_ascii
In [13]: data = {'first': '大牛', 'second': '二狗', 'third': '猫蛋'}
In [14]: json.dumps(data)
Out[14]: '{"first": "\\u5927\\u725b", "second": "\\u4e8c\\u72d7", "third": "\\u732b\\u86cb"}'
In [15]: json.dumps(data, ensure_ascii=False)
Out[15]: '{"first": "大牛", "second": "二狗", "third": "猫蛋"}'
dunps时, 指定了ensure_ascii=False使序列化后的数据不强制使用ascii吗转码, 输出即是中文
2.3.4 allow_nan
In [9]: data = {'float': 1.2, 'nan': float('nan'), 'inf': float('inf')}
In [10]: data
Out[10]: {'float': 1.2, 'nan': nan, 'inf': inf}
In [11]: json.dumps(data)
Out[11]: '{"float": 1.2, "nan": NaN, "inf": Infinity}'
In [12]: json.dumps(data, allow_nan=False)
ValueError: Out of range float values are not JSON compliant
指定allow_nan=False之后, 被序列化对象包含,超出范围的float数据, 报ValueError
2.3.5 default
In [1]: from datetime import datetime
In [2]: import json
In [3]: data = {'date': datetime.now()}
In [3]: json.dumps(data)
TypeError: Object of type datetime is not JSON serializable
In [4]: json.dumps(data, default=lambda x: x.strftime('%Y/%m/%d %H:%M'))
Out[4]: '{"date": "2021/08/13 11:03"}'
数据data中包含无法被序列化的对象, date字段为datetime.datetime格式的数据, 直接调用json.dumps报TypeError, 指定default函数之后, 对date的字段应用函数转换成字符串格式, 序列化成功.
2.3.6 indent
In [5]: data = {'lgd': {'players': ['ame', 'nothingtosay', 'faith_bian', 'xinQ', 'y`'], 'coach': 'xiao8'}, 'VG': {'players': ['poyoyo', 'ori', 'old_eleven', 'pyw', 'dy']}}
In [6]: print(json.dumps(data))
{"lgd": {"players": ["ame", "nothingtosay", "faith_bian", "xinQ", "y`"], "coach": "xiao8"}, "VG": {"players": ["poyoyo", "ori", "old_eleven", "pyw", "dy"]}}
In [7]: print(json.dumps(data, indent=4))
{
"lgd": {
"players": [
"ame",
"nothingtosay",
"faith_bian",
"xinQ",
"y`"
],
"coach": "xiao8"
},
"VG": {
"players": [
"poyoyo",
"ori",
"old_eleven",
"pyw",
"dy"
]
}
}
dumps时, 设置indent=4, 数据增加换行符, 数据层级以4个空格为缩进.
2.3.7 separator
In [8]: data
Out[8]: {'key': 'value', 'border': 'lands'}
In [9]: json.dumps(data)
Out[9]: '{"key": "value", "border": "lands"}'
In [10]: json.dumps(data, separators=(',', ':'))
Out[10]: '{"key":"value","border":"lands"}'
In [11]: json.dumps(data, separators=('&', '@'))
Out[11]: '{"key"@"value"&"border"@"lands"}'
默认数据分割符为 ', ' 和 ': ', 通过指定separators=(',', ':')去除空格后, 可以使序列化后的数据更加紧凑. 甚至可以自定义连接符来dump成自定义的数据样式.
2.3.8 check_circular
In [21]: data = {'key': 'value', 'border': 'lands'}
In [22]: data['data'] = data
In [23]: data
Out[23]: {'key': 'value', 'border': 'lands', 'data': {...}}
In [24]: json.dumps(data)
---------------------------------------------------------------------------
ValueError: Circular reference detected
In [25]: json.dumps(data, check_circular=False)
---------------------------------------------------------------------------
RecursionError: maximum recursion depth exceeded while encoding a JSON object
当data中存在对自己的递归引用时, json.dumps 会报ValueError, 指定指定check_circular=False后, 不进行循环引用检验.
总结:
本文总结了python内置模块json的常用方法 dump和load
序列化过程中的一些参数控制总结:
① 无法序列化的数据, key的跳过, value使用函数转换
② 数据的排序, 编码, 非法float数据
③ 缩进和分隔符
需要更高级的对JSON数据的处理方法,参见 :
更多推荐
所有评论(0)