根据JSON规范, 一个JSON数据中, 可以只包含一个值, 而不是一个完整的对象. 这个值可以是一个字符串, 一个数字, 布尔值, 空值, 或者一个数组. 除了这三种JSON规范中给出的类型, 还可以是NaN, Infinity或者-Infinity:
>>> json.loads('"hello"')
'hello'
>>> json.loads('123')
123
>>> json.loads('123.34')
123.34
>>> json.loads('true')
True
>>> json.loads('false')
False
>>> print(json.loads('null'))
None
>>> json.loads('[1, 2, 3]')
[1, 2, 3]
2.8 重复键名
在同一层级JSON对象中, 不应当出现重复的键名, 不过JSON规范中没有给出这种情况的处理标准. 在json.loads中, 当JSON数据中有重复键名, 则后面的键值会覆盖前面的:
>>> json.loads('{"a": 123, "b": "ABC", "a": 321}')
{'a': 321, 'b': 'ABC'}
2.9 处理JSON��据文件
当JSON数据是保存在一个文件中的时候, json.load方法可以用来从这个文件中读取数据, 并转换为Python对象. json.load方法的第一个参数就是指向JSON数据文件的文件类型对象.
比如/tmp/data.json文件的内含如下:
{
"a": 123,
"b": "ABC"
}
可以使用下例中的代码来读取并转化文件中的JSON数据:
>>> with open('/tmp/data.json') as jf:
... json.load(jf)
...
{u'a': 123, u'b': u'ABC'}
除了文件类型的对象, 只要是实现了read方法的类文件对象, 都可以作为fp参数, 比如下例中的io.StringIO:
>>> sio = io.StringIO('{"a": 123}')
>>> json.load(sio)
{'a': 123}
json.load方法的其他参数的意义和使用方法和上文中的json.loads相同, 这里不再赘述.
3 生成JSON
json.dumps方法可以将Python对象转换为一个表示JONS数据的字符串. 它的完整接口签名如下:
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
它的第一个参数obj即为要转换的数据对象.
>>> json.dumps({'a': 123, 'b': 'ABC'})
'{"a": 123, "b": "ABC"}'
3.1 编码格式
json.dumps的ensure_ascii参数用来控制生成的JSON字符串的编码. 其默认值为True, 此时, 所有的非ASCII码字条都会转义. 如果不希望自动进行转义, 则会保持原有编码, 限UTF-8. 如下例所示:
>>> json.dumps({'数字': 123, '字符': '一二三'})
'{"\\u6570\\u5b57": 123, "\\u5b57\\u7b26": "\\u4e00\\u4e8c\\u4e09"}'
>>> json.dumps({'数字': 123, '字符': '一二三'}, ensure_ascii=False)
'{"数字": 123, "字符": "一二三"}'
3.2 数据类型转换
在默认实现中, json.dumps可以处理的Python对象, 及其所有的属性值, 类型必须为dict, list, tuple, str, float或者int. 这些类型与JSON的数据转换关系如下表:
PythonJSONdict object
list, tuple array
str string
int, float, int-&float-derived emuns number
True true
False false
None null
实际转换情况如下示例:
>>> json.dumps(
... {
... 'str': 'ABC',
... 'int': 123,
... 'float': 321.45,
... 'bool_true': True,
... 'bool_false': False,
... 'none': None,
... 'list': [1, 2, 3],
... 'tuple': [12, 34]
... }
... )
'{"str": "ABC", "int": 123, "float": 321.45, "bool_true": true, "bool_flase": false, "none": null, "list": [1, 2, 3], "tuple": [12, 34]}'
虽然JSON标准规范不支持NaN, Infinity和-Infinity, 但是json.dumps的默认实现会将float('nan'), float('inf')和float('-inf')转换为常量NaN, Infinity, 和-Infinity. 如下例所示:
>>> json.dumps(
... {
... 'nan': float('nan'),
... 'inf': float('inf'),
... '-inf': float('-inf')
... }
... )
'{"nan": NaN, "inf": Infinity, "-inf": -Infinity}'