文章目录
JSON文件介绍
1.1 什么是JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。
1.2 JSON语法规则
JSON 语法是 JavaScript 对象表示法语法的子集。
- 数据在名称/值对中
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
JSON 数据的书写格式是:名称:值对。
名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值:
“firstName” : “John”
这很容易理解,等价于这条 JavaScript 语句:
firstName = “John”
JSON 值可以是:
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true 或 false)
- 数组(在方括号中)
- 对象(在花括号中)
- null
1.3 JSON举例
[
{
"asset_type": "路由器",
"production_state": "库存",
"asset_owner_type": null,
"name": "lhx0055",
"asset_sn": "lhx00722",
"dev_sn": "lhx00722",
"is_mount": true,
"buy_time": null,
},
{
"asset_type": "路由器",
"production_state": "库存",
"asset_owner_type": null,
"name": "lhx0056",
"asset_sn": "lhx007221",
"dev_sn": "lhx007222",
"is_mount": false,
"buy_time": null,
}
]
1.4 JSON和XML比较
1.4.1 XML的优缺点
1.4.1.1 XML的优点
- 格式统一,符合标准;
- 容易与其他系统进行远程交互,数据共享比较方便。
1.4.1.2 XML的缺点
- XML文件庞大,文件格式复杂,传输占带宽;
- 服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;
- 客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;
- 服务器端和客户端解析XML花费较多的资源和时间。
1.4.2 JSON的优缺点
1.4.2.1 JSON的优点
- 数据格式比较简单,易于读写,格式都是压缩的,占用带宽小;
- 易于解析,客户端JavaScript可以简单的通过eval()进行JSON数据的读取;
- 支持多种语言,包括ActionScript, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等服务器端语言,便于服务器端的解析;
- 因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护。
1.4.2.2 JSON的缺点
- 没有XML那么通用性,不具有扩展性;
1.3.3 综合分析
综上所述,在相同带宽和流量的情况下,同一时间内,能够为我们传输更多的数据,处理更多的逻辑的JSON才是现在的主流配置,在互联网起步阶段,XML曾经辉煌过,但这已经是一种过去式,就像诺基亚手机一样,慢慢的淹没在历史长河中。
2.1 使用python操作JSON
2.1.1 常规方法
方法 | 实现功能 |
---|---|
json.dumps | 将python对象序列化为JSON字符串 |
json.loads | 将JSON字符串反序列化为python对象 |
json.dump | 将python对象序列化到文件中 |
json.load | 将文件流中的JSON字符串反序列化为python对象 |
2.1.2 序列化中常见问题
2.1.2.1 序列化时,中文字符显示乱码如何处理
序列化时把ensure_ascii
设置成False
就可以了。
2.1.2.2 自定义对象如何支持JSON序列化
- 方式一
import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
def student2dict(std): # 对象转字典,不是类内部方法
return {
'name': std.name,
'age': std.age,
'score': std.score
}
def dict2student(d): # 字典转对象,不是类内部方法
return Student(d['name'], d['age'], d['score'])
# 自定义对象进行JSON序列化
print(json.dumps(s, default=student2dict))
# JSON反序列化回自定义对象
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str, object_hook=dict2student),ensure_ascii=False)
- 方式二(只支持JSON序列化)
import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
s = Student(name='lisi',age = 18, score = 99.8)
print(json.dumps(s, default=lambda obj: obj.__dict__))
# {"name": "lisi", "age": 18, "score": 99.8}
2.1.2.3 时间类型以及uuid类型如何进行序列化
- 列表或者字典中的时间类型和uuid类型
继承json.JSONEncoder类,重写default方法,添加时间类型的处理:
import json
from datetime import datetime,date
import uuid
class CJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(obj, date):
return obj.strftime('%Y-%m-%d')
elif: isinstance(obj,uuid.UUID):
return str(obj)
else:
return super().default(obj)
l = ['12',date.today(),datetime.today(),uuid.uuid4()]
print(json.dumps(l, cls=CJsonEncoder))
# ["12", "2020-11-25", "2020-11-25 16:40:42", "6c809fcf-baad-4236-81f2-f01200314ea9"]
- 自定义对象中的时间类型和uuid类型
import json
from datetime import datetime,date
class Foo(object):
def __init__(self,name,age,birth):
self.name = name
self.age = age
self.birth =birth
def obj2dict(self,obj):
return {
'name':obj.name,
'age':obj.age,
'birth':obj.birth.strftime('%Y-%m-%d')
}
f = Foo('xx',18,date.today())
json.dumps(f, default=f.obj2dict)
# {"name": "xx", "age": 18, "birth": "2020-11-25"}
2.1.3 封装工具类
import uuid
import json
from datetime import datetime, date
class CJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(obj, date):
return obj.strftime('%Y-%m-%d')
elif isinstance(obj, uuid.UUID):
return str(obj)
else:
return super().default(obj)
class JSONHelper(object):
@staticmethod
def obj_to_json(obj):
return json.dumps(obj, ensure_ascii=False, default=None, cls=CJsonEncoder)
@staticmethod
def json_to_obj(json_str, object_hook=None):
return json.loads(json_str, object_hook=object_hook)
@staticmethod
def obj_to_json_file(obj, file_path):
with open(file_path, 'w') as fp:
return json.dump(obj, fp, ensure_ascii=False, default=None, cls=CJsonEncoder)
@staticmethod
def json_file_to_obj(file_path, object_hook=None, encoding='utf8'):
with open(file_path, 'rb') as fp:
return json.load(fp, object_hook=object_hook, encoding=encoding)
2.1.4 调用代码举例
# 对象转化为json字符串
obj = [{ 'user_info': { 'name': 'zhangsan', 'age': 18, 'gender': '男', 'is_admin': True, 'date': date.today()}},
{ 'connect': { 'host': '127.0.0.1', 'user': 'db', 'password': 123456, 'port': 1521, 'db': 'zet'}}]
json_str = JSONHelper.obj_to_json(obj)
# 将对象转化为JSON字符串写入文件
save_path = 'obj.json'
JSONHelper.obj_to_json_file(obj, save_path)
print(type(json_str)) # <class 'list'>
print(json_str)
# [{"user_info": {"name": "zhangsan", "age": 18, "gender": "男", "is_admin": true, "date": "2020-11-25"}},
# {"connect": {"host": "127.0.0.1", "user": "db", "password": 123456, "port": 1521, "db": "zet"}}]
# json字符串转对象
str1 = """ [{"user_info": {"name": "zhangsan", "age": 18, "gender": "男", "is_admin": true}}] """
obj1 = JSONHelper.json_to_obj(str1)
print(type(obj1)) # <class 'list'>
print(obj1)
# [{'user_info': {'name': 'zhangsan', 'age': 18, 'gender': '男', 'is_admin': True}}]
# 读取接送文件到对象
file_path = 'data.json'
obj2 = JSONHelper.json_file_to_obj(file_path)
print(type(obj2))
print(obj2)