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)

 

posted @ 2021-05-24 00:26  麦恒  阅读(136)  评论(0编辑  收藏  举报