JSON表示JavaScript Object Notation,是一种纯文本的格式,所以可以用任何文本编辑打开保存为JSON的文件。
JSON对象的基本格式:{"key":value}。键必须是一个字符串,必须用双引号括起来,值可以是任何对象。
格式化JSON的值:
数据类型 | 格式 | 备注 |
String | "string" | 必须要用双引号 |
Number | 1或1.3 | 可以使用一个整数或浮点数 |
Boolean | true或false | 没有引号,没有大写 |
Array | ["thing","thing"] | 可以用方括号保存任何的数据类型 |
JSON object | {"key":value} | 和Python的字典不同,这个字典必须有一个用作键的字符串 |
Null | null | 没有引号,没有大写 |
注意:每个JSON文件只能保存一个JSON对象。如果有多个对象,应该把每个对象都保存到一个新的文件中,或把每个对象放到一个父级JSON对象中。
{"Niko":"cat"}
{"Scruffy":"dog"}
#无效
{"pets":[{"Niko":"cat"},
{"Scruffy":"dog"}]
}#有效
1.使用JSON文件
要使用JSON,必须导入Python的JSON库
import json
首先打开文件,然后把它保存成一个流文件(f)。然后,使用JSON库,用load()函数把JSON对象的内容加载到一个新的变量中
>>> import json
>>> f=open('pet.json')
>>> pet=json.load(f)
>>> pet
{'pets': {'Niko': 'cat', 'Scruffy': 'dog'}}
>>> type(pet)
<class 'dict'>
load()函数并没有创建一个JSON对象,它创建了一个字典。
注意:在JOSN文件中小写的true和false,已经转换成字典中大写的True和False。
2.将JSON保存到文件中,使用dump()函数。
我们修改Niko的属性,如下
>>> import json
>>> f=open('pet.json')
>>> pet=json.load(f)
>>> f.close()
>>> pet['pets']['Niko']='rabbit'
>>> f=open('pet.json','w')
>>> json.dump(pet,f)
>>> f.close()
>>> f=open('pet.json')
>>> json.load(f)
{'pets': {'Niko': 'rabbit', 'Scruffy': 'dog'}}
这里所有的文本都在一行,可读性不好,可以给dump()函数传送一个参数indent,以得到更好的格式。
给indent一个整数,Python会格式化JOSN,以便每个键/值对都是独立的一行,并且插入制表符以便能够区分键/值对是如何分组的。如下
>>> f=open('pet.json','w')
>>> json.dump(pet,f,indent=2)
>>> f.close()
当打开JSON文件时,会看到如下内容
{
"pets": {
"Niko": "rabbit",
"Scruffy": "dog"
}
}
3.只显示JSON,而不把它保存到一个文件中。用json.dumps(),它接受有效的JSON,将其作为一个字符串返回,也接受indent参数,可以根据需要来格式化这个JSON
>>> f=open('pet.json')
>>> pet=json.load(f)
>>> print(json.dumps(pet,indent=2))
{
"pets": {
"Niko": "rabbit",
"Scruffy": "dog"
}
}
4.vars()内建函数,它返回一个字典,其中带有一个对象的所有属性,这些属性可以用来创建一个有效的JSON。
首先我们在一个car.py的文件中,创建一个类,如下
class Car(object):
def __init__(self,make,model,doors=5,features={}):
self.make=make
self.model=model
self.doors=doors
self.features=features
创建一个Car实例,然后使用vars()函数
>>> from car import Car
>>> mycar=Car(make='ford',model='Explo',doors=6,features={"stow":True})
>>> vars(mycar)
{'make': 'ford', 'model': 'Explo', 'doors': 6, 'features': {'stow': True}}
创建一个新的JSON文件,以'w'的模式打开
>>> import json
>>> f=open('newcar.json','w')
>>> json.dump(vars(mycar),f,indent=2)
>>> f.close()
在你打开的json文件中,
{
"make": "ford",
"model": "Explo",
"doors": 6,
"features": {
"stow": true
}
}
所有的属性都已经保存,并且格式也是有效的(布尔值True是小写的,并且也使用了双引号)。
5.生成带有定制类的JSON文件。
如果类包含了另一个对象,会发生什么?
classroom.py文件中的内容
class Classroom(object):
def __init__(self,room_number="",students=[]):
self.students=students
self.room_number=room_number
class Student(object):
def __init__(self,name,grade):
self.name=name
self.grade=grade
当我们在Shell中测试,查看当我们试图得到字典时
>>> from classroom import *
>>> student1=Student("jsdf","1")
>>> student2=Student("al","1")
>>> first_grade=Classroom(students=[student1,student2],room_number="B233")
>>> print(vars(student1))
{'name': 'jsdf', 'grade': '1'}
>>> print(vars(first_grade))
{'students': [<classroom.Student object at 0x03F1D210>, <classroom.Student object at 0x03F2C8F0>], 'room_number': 'B233'}
>>> import json
>>> json.dumps(vars(first_grade))
Traceback (most recent call last):
File "<pyshell#64>", line 1, in <module>
json.dumps(vars(first_grade))
File "F:\大学\python\lib\json\__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "F:\大学\python\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "F:\大学\python\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "F:\大学\python\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Student is not JSON serializable
如上,first_grade有问题,然后通过查找,我们发现JSON库和类之间有些问题,这时我们可以在Classroom类中添加一个函数,如下:
def get_JSON_dict(self):
d=vars(self)
student_list=[]
for student in self.students:
student_list.append(vars(student))
d['students']=student_list
return d
再次测试
>>> print(first_grade.get_JSON_dict())
{'students': [{'name': 'jack', 'grade': '1'}, {'name': 'al', 'grade': '1'}], 'room_number': 'bdf'}
>>> print(vars(student1))
{'name': 'jsdf', 'grade': '1'}
其他标准格式:CSV格式,它像电子数据表格一样工作。另一种通用格式是XML,常用于RSS Feed。
想使用没有Python库支持的格式,如果一种格式相当标准,也许有人会为它编写一个模块。
要查看是否有为你的格式而编写的库,请搜索“Python module”加上你的文件格式(eg:“Microsoft Excel”)
使用标准化的格式而不是一个定制的格式的原因是一个标准化的格式可以被多种语言读取,并且无需查找如何解析其中的信息就可以使用它。
json.dump()用来把JSON传送到一个数据流,而json.dumps()以字符串形式返回一个有效的JSON
vars()把一个对象中所存储的所有属性返回到一个字典中