Json文件格式及Python对其的基本使用

1、简要介绍

  JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。易于人阅读和编写,可以在多种语言之间进行数据交换。同时也易于机器解析和生成。
  JSON是Douglas Crockford在2001年开始推广使用的数据格式,在2005年-2006年正式成为主流的数据格式。

2、JSON语法

  JSON是一个标记符的序列。这套标记符包含六个构造字符字符串数字和三个字面名
  JSON是一个序列化的对象 (object) 或数组 (array)。

六个构造字符

对象的开始:{ 左大括号
对象的结束:} 右大括号
数组的开始:[ 左方括号
数组的结束:] 右方括号
键值之间的分隔::冒号
值之间的分隔:,逗号

JSON的值

  可以是对象、数组、数字、字符串或者三个字面值 (false、null、true) 中的一个。值中的字面值中的英文必须使用小写字母。
  对象由花括号括起来的逗号分隔的成员构成,成员是字符串键和上文所述的值由冒号分隔的键值对组成,如:

{"name": "John Doe", "age": 18, "address": {"country": "china", "zip-code": "10000"}}

  JSON中的对象可以包含多个键值对。

  数组是由方括号括起来的一组值构成,如:

[3, 1, 4, 2, 5, 6, 4, 7]

  字符串是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。

  数字与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。
  一些合法的JSON实例:

{"a": 1, "b": [1, 2, 3]}
[1, 2, "3", {"a": 4}]
3.14
"plain_text"

注意事项
1、JSON中没有undefined
2、JSON中的字符串必须使用双引号,对象的属性名必须是双引号,属性值如果是字符串也必须是双引号
3、JSON中不能使用注释

3 Python对JSON的基本使用

Python与JSON数据类型的映射关系

Python JSON
dict object
list, tuple array
string, unicode string
int, long, float number
True true
False false
None null

Python对JSON的常用方法

Python在使用json这个模块前,首先要导入json库:import json.

方法 描述
json.dumps() 将Python对象编码成JSON字符串
json.loads() 将已编码的JSON字符串解码为Python对象
json.dump() 将Python内置类型序列化为json对象后写入文件
json.load() 读取文件中json形式的字符串元素转化为Python类型
**注意:**不带s的是序列化到文件或者从文件反序列化,带s的都是内存操作不涉及持久化。

json.dumps()

import json

python_data = {'name': 'April', 'age': 18}
json_str = json.dumps(python_data)
print(json_str)

结果

{"name": "April", "age": 18}

:原先的单引号已经变成双引号了

json.loads()

import json

python_data = {'name': 'April', 'age': 18}
json_str = json.dumps(python_data) #将Python对象编码成json字符串
python_data2 = json.loads(json_str) #将json字符串解码成Python对象
print(python_data2)

结果

{"name": "April", "age": 18}

接下来是元组和列表的例子

import json

data_tuple = (1, 2, 3, 4)
data_list = [1, 2, 3, 4]

#将Python对象编码成json字符串
json_tuple = json.dumps(python_data)
json_list = json.dumps(python_data)
print(json_tuple)
print(json_list)

#将json字符串解码成Python对象
data_tuple2 = json.loads(json_tuple) 
data_list2 = json.loads(json_list) 
print(data_tuple2)
print(data_list2)

结果

[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]

  从以上结果可以看出,Python中的list和tuple在编码过程中都被转化为json中的数组;json的数组在解码过程中转化为Python中的list,无论原来是list还是tuple。

json.dump()

  将Python内置类型序列化为json对象后写入文件:

import json

data = {
    'name': 'April', 
    'a': [1, 2, 3, 4],
    'b': (1, 2, 3, 4)
    }
    
with open ('json_test.json', 'w+') as f:
    json.dump(data, f)

json.load()

  读取文件中json形式的字符串元素转化为Python类型:

import json

data = {
    'name': 'April', 
    'a': [1, 2, 3, 4],
    'b': (1, 2, 3, 4)
    }
    
with open ('json_test.json', 'w+') as f:
    json.dump(data, f)
    
with open ('json_test.json', 'r+') as f:
    print(json.load(f))

结果

{'name': 'April', 'a': [1, 2, 3, 4], 'b': [1, 2, 3, 4]}

更多实例

json.dumps( ):将一个Python数据类型列表编码成json格式的字符串

#python的列表转换为json的数组
>>> import json
>>> json.dumps([1,2,3])
'[1, 2, 3]'
#python的字符串转换为json的字符串
>>> json.dumps('abdcs')
'"abdcs"'
#python的元祖转换为json的数组
>>> json.dumps((1,2,3,'a'))
'[1, 2, 3, "a"]'#注意此时显示的是方括号
#python的字典转换为json的对象
>>> json.dumps({1:'a',2:'b'})
'{"1": "a", "2": "b"}'#注意此时1和2转换后是加了引号的,因为json的名称是必须要加引号的
#python的整数转换为json的数字
>>> json.dumps(13)
'13'
#python的浮点数转换为json的数字
>>> json.dumps(3.1415)
'3.1415'
#python的unicode字符串转换为json的字符串
>>> json.dumps(u'a')
'"a"'
#python的True转换为json的数组true
>>> json.dumps(True)
'true'
#python的False转换为json的数组false
>>> json.dumps(False)
'false'
#python的None转换为json的null
>>> json.dumps(None)
'null'
#json本质上是一个字符串
>>> type(json.dumps('abc'))
<class 'str'>

dump和dumps:

import json

# dumps可以格式化所有的基本数据类型为字符串
data1 = json.dumps([])         # 列表
print(data1, type(data1))
data2 = json.dumps(2)          # 数字
print(data2, type(data2))
data3 = json.dumps('3')        # 字符串
print(data3, type(data3))
dict = {"name": "Tom", "age": 23}   # 字典
data4 = json.dumps(dict)
print(data4, type(data4))

with open("test.json", "w", encoding='utf-8') as f:
    # indent格式化保存字典,默认为None,小于0为零个空格
    f.write(json.dumps(dict, indent=4))
    json.dump(dict, f, indent=4)  # 传入文件描述符,和dumps一样的结果

得到的输出结果如下:格式化所有的数据类型为str类型:

[] <class 'str'>
2 <class 'str'>
"3" <class 'str'>
{"name": "Tom", "age": 23} <class 'str'>

test.json中的内容:

{
    "name": "Tom",
    "age": 23
}

load和loads:

import json

dict = '{"name": "Tom", "age": 23}'   # 将字符串还原为dict
data1 = json.loads(dict)
print(data1, type(data1))

with open("test.json", "r", encoding='utf-8') as f:
    data2 = json.loads(f.read())    # load的传入参数为字符串类型
    print(data2, type(data2))
    f.seek(0)                       # 将文件游标移动到文件开头位置
    data3 = json.load(f)
    print(data3, type(data3))

结果如下:

{'name': 'Tom', 'age': 23} <class 'dict'>
{'name': 'Tom', 'age': 23} <class 'dict'>
{'name': 'Tom', 'age': 23} <class 'dict'>

常见的错误

读取多行JSON文件
加入读取如下多行JSON文件:

{"坂": ["坂5742"]}
{"构": ["构6784"]}
{"共": ["共5171"]}
{"钩": ["钩94a9"]}
{"肮": ["肮80ae"]}
{"孤": ["孤5b64"]}

直接使用:

with open(json_path, 'r') as f:
    json_data = json.load(f)

会抛出异常: JSONDecodeError

json只能读取一个文档对象,有两个解决办法:
1、单行读取文件,一次读取一行文件。
2、保存数据源的时候,格式写为一个对象(dump)。

1、单行读取文件:

with open(json_path, 'r') as f:
    for line in f.readlines():
        json_data = json.loads(line)

如果JSON文件中包含空行,还是会抛出JSONDecodeError异常。
可以先处理空行,再进行文件读取操作:

for line in f.readlines():
      line = line.strip()   # 使用strip函数去除空行
      if len(line) != 0:
          json_data = json.loads(line)

2. 合并为一个对象:
将json文件处理成一个对象文件(序列化):

{"dict": [
{"坂": ["坂5742"]},
{"构": ["构6784"]},
{"共": ["共5171"]},
{"钩": ["钩94a9"]},
{"肮": ["肮80ae"]},
{"孤": ["孤5b64"]}
]}

然后再用:

with open(json_path, 'r') as f:
     json_data = json.loads(f.read())

你可能感兴趣的:(Python基础学习,python,json,开发语言)