python模块 json--操作文件json
本文使用的python3.8:https://docs.python.org/zh-cn/3.8/library/json.html#module-json
1、json数据
1、json简介
- JSON的全称是”JavaScript Object Notation”,意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式。XML也是一种数据交换格式。
- XML也可以作为跨平台的数据交换格式,但是在JS(JavaScript的简写)中处理XML非常不方便,同时XML标记比数据多,增加了交换产生的流量。JSON没有附加的任何标记,在JS中可作为对象处理,所以我们更倾向于选择JSON来交换数据。
2、JSON的两种结构
- JSON有两种表示结构,对象和数组。
1、对象
- 对象结构以花括号”{”开始,以花括号”}”结束。数据部分由0或多个以逗号”,”分隔的”key(关键字)/value(值)”对构成,关键字和值之间以冒号”:”分隔,语法结构如代码。
- 关键字必须是字符串,而值可以是字符串、数值、true、false、null、对象或数组。
{ key1:value1, key2:value2, ... }
2、数组
- 数组结构以中括号”[”开始,中括号”]”结束。中间由0或多个以逗号”,”分隔的值列表组成,语法结构如代码。
[ { key1:value1, key2:value2 }, { key3:value3, key4:value4 } ]
示例:
#对象 { "firstName": "Brett", "lastName": "McLaughlin" } #对象套嵌对象 { "name": "John Doe", "age": 18, "address": { "country" : "china", "zip-code": "10000" } } #对象套嵌数组 { "a": 1, "b": [1, 2, 3] } #数组 [3, 1, 4, 1, 5, 9, 2, 6] #数组套嵌对象 [3, 1, 4, {"firstName": "Brett", "lastName": "McLaughlin"}] [ 3, 1, 4, { "firstName": "Brett", "lastName": "McLaughlin" } ]
2、json模块方法
- json模块,用于字符串和python数据类型间进行转换,即python数据和json数据之间的转换。
1、json.dump方法
json.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)
- 如果skipkeys是True(默认为False),那些字典的键不是基本对象(包括str、int、float、bool、None)的会被跳过;否则引发一个TypeError。。
- 如果ensure_ascii是True(即默认值),输出将所有输入的非ASCII字符转义。如果ensure_ascii是false,这些字符会原样输出。
- 如果check_circular是为False(默认为True),那么容器类型的循环引用检验会被跳过并且循环引用会引发一个OverflowError(或者更糟的情况)。
- 如果allow_nan是false(默认为True),那么在对严格JSON规格范围外的float类型值(nan、inf和-inf)进行序列化时会引发一个ValueError。如果allow_nan是true,则使用它们的JavaScript等价形式(NaN、Infinity和-Infinity)。
- 如果indent是一个非负整数或者字符串,那么JSON数组元素和对象成员会被美化输出为该值指定的缩进等级。如果缩进等级为零、负数或者"",则只会添加换行符。None(默认值)选择最紧凑的表达。使用一个正整数会让每一层缩进同样数量的空格。如果indent是一个字符串(比如"\t"),那个字符串会被用于缩进每一层。在3.2版更改:现允许使用字符串作为indent而不再仅仅是整数。
- 当被指定时,separators应当是一个(item_separator,key_separator)元组。当indent为None时,默认值取(', ', ': '),否则取 (',', ': ')。为了得到最紧凑的JSON表达式,你应该指定其为(',', ':')以消除空白字符。在3.4版更改:现当indent不是None时,采用(',', ': ')作为默认值。
- 当default被指定时,其应该是一个函数,每当某个对象无法被序列化时它会被调用。它应该返回该对象的一个可以被JSON编码的版本或者引发一个TypeError。如果没有被指定,则会直接引发TypeError。
- 如果sort_keys是true(默认为False),那么字典的输出会以键的顺序排序。
- 为了使用一个自定义的JSONEncoder子类(比如:覆盖了default()方法来序列化额外的类型),通过cls关键字参数来指定;否则将使用JSONEncoder。在3.6版更改:所有可选形参现在都是仅限关键字参数。
示例:
- json.dump将pyhton中字典hh编码成json中的对象,并保存在text.txt文件中。
import json hh = {"c": 0, "b": 0, "a": 0} #字典 with open('text.txt', mode='w') as fp1: json.dump(hh, fp1)
2、json.dumps方法
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)
- 使用这个“Python编码为JSON,类型转换对应表”将obj序列化为JSON格式的str。其参数的含义与dump()中的相同。
- JSON中的键-值对中的键永远是str类型的。当一个对象被转化为JSON时,字典中所有的键都会被强制转换为字符串。这所造成的结果是字典被转换为JSON然后转换回字典时可能和原来的不相等。
示例1:对基本的Python对象层次结构进行编码
import json print(json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])) print(json.dumps("\"foo\bar")) print(json.dumps('\u1234')) print(json.dumps('\\')) <<< ["foo", {"bar": ["baz", null, 1.0, 2]}] "\"foo\bar" "\u1234" "\\"
示例2:字典的输出会以键的顺序排序
import json print(json.dumps({"c": 0, "b": 0, "a": 0})) print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)) <<< {"c": 0, "b": 0, "a": 0} {"a": 0, "b": 0, "c": 0}
示例3:美化输出
import json print(json.dumps([1, 2, 3, {'4': 5, '6': 7}])) #默认indent=None,默认separators=(', ', ': '),逗号和冒号后都有空格 print(json.dumps([1, 2, 3, {'4': 5, '6': 7}], separators=(',', ':'))) #separators=(',', ':'),逗号和冒号后都没有空格 print(json.dumps([1, 2, 3, {'4': 5, '6': 7}], indent=4)) #indent=4,默认separators=(',', ': '),逗号后没有空格,冒号后都有空格 <<< [1, 2, 3, {"4": 5, "6": 7}] [1,2,3,{"4":5,"6":7}] [ 1, 2, 3, { "4": 5, "6": 7 } ]
示例4:
import json from io import StringIO io = StringIO() json.dump(['streaming API'], io) print(io.getvalue()) <<< ["streaming API"]
3、json.load方法
json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
- object_hook是一个可选的函数,它会被调用于每一个解码出的对象字面量(即一个dict)。object_hook的返回值会取代原本的dict。这一特性能够被用于实现自定义解码器(如JSON-RPC的类型提示)。
- object_pairs_hook是一个可选的函数,它会被调用于每一个有序列表对解码出的对象字面量。object_pairs_hook的返回值将会取代原本的dict。这一特性能够被用于实现自定义解码器。如果object_hook也被定义,object_pairs_hook优先。在3.1版更改:添加了对object_pairs_hook的支持。
- parse_float,如果指定,将与每个要解码JSON浮点数的字符串一同调用。默认状态下,相当于float(num_str)。可以用于对JSON浮点数使用其它数据类型和语法分析程序(比如decimal.Decimal)。
- parse_constant,如果指定,将要与以下字符串中的一个一同调用:'-Infinity','Infinity','NaN'。如果遇到无效的JSON数字则可以使用它引发异常。在3.1版更改:parse_constant不再调用'null','true','false'。
- 要使用自定义的JSONDecoder子类,用cls指定他;否则使用JSONDecoder。额外的关键词参数会通过类的构造函数传递。
示例:
- json.load将text.txt文件中json数据读取出来,并解码为python数据。
#text.txt #{"c": 0, "b": 0, "a": 0} import json with open('text.txt', mode='r') as fp2: a = json.load(fp2) print(a, type(a)) <<< {'c': 0, 'b': 0, 'a': 0} <class 'dict'>
4、json.loads方法
json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
- 使用这个“JSON解码为Python,类型转换对应表”将s(一个包含JSON文档的str,bytes或bytearray实例)反序列化为Python对象。
- 自Python3.1以来,除了*encoding*被忽略和弃用,其他参数的含义与load()中相同。
- 如果反序列化的数据不是有效JSON文档,引发JSONDecodeError错误。
- 在3.6版更改:s现在可以为bytes或bytearray类型。输入编码应为UTF-8,UTF-16或UTF-32。
- json.loads对象必须是str, bytes或bytearray。
import json print(json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')) #JSON对象必须是str, bytes或bytearray print(json.loads('[1,2,3,{"4":5,"6":7}]')) print(json.loads('{"c": 0, "b": 0, "a": 0}')) <<< ['foo', {'bar': ['baz', None, 1.0, 2]}] [1, 2, 3, {'4': 5, '6': 7}] {'c': 0, 'b': 0, 'a': 0}
3、dump和dumps、load和loads的区别
- dumps是将dict(字典)转化成str(字符串)格式,即将python数据编码成json数据。直接返回转化后的字符串。
- loads是将str(字符串)转化成dict(字典)格式,即将json数据解码成python数据。loads操作的是字符串。
- dump将python数据编码成json数据,并保存在文件中。
- load从文件中读取json数据,并将json数据解码成python数据。load操作的是文件流。
- dump(load)与dumps(loads)的功能一样,只是与文件操作结合起来了。
import json hh = {"c": 0, "b": 0, "a": 0} #字典 a1 = json.dumps(hh) #将python数据转化为json数据,并直接返回转化后的字符串。 print(a1, type(a1)) b1 = json.loads(a1) #将json数据转化为python数据,并直接返回转化后的字典 print(b1, type(b1)) with open('text.txt', mode='w') as fp1: json.dump(hh, fp1) #将python数据转化为json数据,并直转化后的字符串保存在文件中 with open('text.txt', mode='r') as fp2: a = json.load(fp2) #从文件中读取json数据,并将json数据解码成python数据,最后直接返回转化后的字典。 print(a, type(a)) <<< {"c": 0, "b": 0, "a": 0} <class 'str'> {'c': 0, 'b': 0, 'a': 0} <class 'dict'> {'c': 0, 'b': 0, 'a': 0} <class 'dict'>
4、json模块的编码器和解码器
1、简单的JSON解码器
class json.JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)
2、用于Python数据结构的可扩展JSON编码器
class json.JSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)