说明
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
JSON建构于两种结构:
“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)或者列表(list)。
这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。
编码
import json
obj = [[1,2,3],123,123.123,'abc',{'key1':(1,2,3),'key2':(4,5,6)}]
encodejson = json.dumps(obj)
print(repr(obj))
print(encodejson)
>>[[1, 2, 3], 123, 123.123, 'abc', {'key1': (1, 2, 3), 'key2': (4, 5, 6)}]
>>[[1, 2, 3], 123, 123.123, "abc", {"key1": [1, 2, 3], "key2": [4, 5, 6]}]
dumps提供了很多参数可供选择,常用的有sort_keys(对dict对象进行排序),separators,indent等
sort_keys 告诉编码器按照字典key排序(a到z)输出
import json
data1 = {'b':789,'c':456,'a':123}
data2 = {'a':123,'b':789,'c':456}
d1 = json.dumps(data1,sort_keys=True)
d2 = json.dumps(data2)
d3 = json.dumps(data2,sort_keys=True)
print(d1,d2,d3)
>>{"a": 123, "b": 789, "c": 456} {"a": 123, "b": 789, "c": 456} {"a": 123, "b": 789, "c": 456}
indent 根据数据格式缩进显示,读起来更加清晰, indent的值,代表缩进空格式
import json
data1 = {'b':789,'c':456,'a':123}
d1 = json.dumps(data1,sort_keys=True,indent=4)
print(d1)
>>>>
{
"a": 123,
"b": 789,
"c": 456
}
separators参数的作用是去掉‘,’ ‘:’后面的空格,在传输数据的过程中,越精简越好,冗余的东西全部去掉
import json
data1 = {'b':789,'c':456,'a':123}
print('DATA',repr(data1))
print('repr(data1)',len(repr(data1)),sep=':')
print('dumps(data1)',len(json.dumps(data1)),sep=':')
print('dumps(data1,separators)',len(json.dumps(data1,separators=(',',':'))),sep=':')
>>>>
DATA {'b': 789, 'c': 456, 'a': 123}
repr(data1):30
dumps(data1):30
dumps(data1,separators):25
输出真正的中文需要指定ensure_ascii=False
import json
print(json.dumps('中国'))
>>"\u4e2d\u56fd"
print(json.dumps('中国',ensure_ascii=False))
>>"中国"
解码
import json
obj = [[1,2,3],123,123.123,'abc',{'key1':(1,2,3),'key2':(4,5,6)}]
encodejson = json.dumps(obj)
decodejson = json.loads(encodejson)
print(decodejson)
>>[[1, 2, 3], 123, 123.123, 'abc', {'key1': [1, 2, 3], 'key2': [4, 5, 6]}]
json.load()可以用来读取文件:
import json
with open('file.json','r') as f:
result = json.load(f)
json.loads()是用来读取字符串的,如果用这个来读取文件会报错
如果strict为false(默认值为True),则字符串中允许使用控制字符。此上下文中的控制字符是那些字符代码在0–31范围内的字符,包括“\t”(制表符)、“\n”、“r”和“\0”。
import json
lines = []
with open('file.json','r') as f:
for row in f.readlines():
if row.strip().startswith('//'):
continue
lines.append(row)
result=json.loads('\n'.join(lines)) #loads是变为字符串的内容
处理自定义的对象
import json
class Person():
def __init__(self,name,age):
self.name = name
self.age = age
def __repr__(self):
return 'Person object name is {0},age is {1}'.format(self.name,self.age)
if __name__ == '__main__':
p = Person('Peter',22)
print(p)
>>Person object name is Peter,age is 22
def object2dict(obj):
d = dict()
d['__class__'] = obj.__class__.__name__
d['__module__'] = obj.__module__
d.update(obj.__dict__)
return d
def dict2object(d):
if'__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
module = __import__(module_name)
class_ = getattr(module,class_name)
args = dict((key.encode('ascii'), value) for key, value in d.items()) #get args
inst = class_(**args) #create new instance
else:
inst = d
return inst
处理日期类型
datetime 类型无法通过json序列化,需要对其做特殊处理
import json
from datetime import datetime,date
class DateToJson(json.JSONEncoder):
def default(self,obj):
if isinstance(obj,datetime):
return obj.strftime("%Y年%m月%d日 %H:%M:%S")
if isinstance(obj,date):
return obj.strftime("%Y-%m-%d")
else:
return json.JSONEncoder.default(self,obj)
d = {'name':'Bill','time':datetime.now()}
print(json.dumps(d,cls=DateToJson,ensure_ascii=False))
>>d = {'name':'Bill','time':'2022年1月16日 16:57:43'}