Python廖雪峰教程学习笔记:Day14

前言

养成一个好的习惯只需要坚持21天,Day14
什是JSON?
JSON是轻量级的文本数据交换格式,指的是 JavaScript 对象表示法(JavaScript Object Notation),类似XML但又比 XML 更小、更快,更易解析。

JSON语法

JSON数据的书写格式是:"名称":“值”,例如:

"name":"汤姆"

JSON的值可以是:数字、字符串、逻辑值、数组、对象和null。

{"age":30}
{"name":"汤姆""country":"England"}
{"flag":true}
{"money":null}

JSON数组:

{
"sites": [
{ "name":"汤姆" , "country":"England	"}, 
{ "name":"张三" , "country“:”China" }, 
{ "name":"里斯" , "country":"France" }
]
}
JSON与Python对象

在Python的内部有json模块,提供了Python对象到JSON格式的转换。
把Python对象编程一个JSON

>>> import json
>>> d = dict(name='Bob',age=20,score=90)
>>> json.dumps(d)
# '{"name": "Bob", "age": 20, "score": 90}'

json.dumps()方法返回一个str,内容是标准的JSON。类似的,dump()方法可以直接把JSON写入一个file-like Objectfile-like Object是像open()函数返回的这种有个read()方法的对象,除了file外,还可以是内存的字节流,网络流,自定义流等等。
把JSON反序列化为Python对象

>>> json_str = '{"name": "Bob", "age": 20, "score": 90}'
>>> json.loads(json_str)
# {'name': 'Bob', 'age': 20, 'score': 90}

json.loads()函数把JSON的字符串反序列化,json.load()函数从file-like Object中读取字符串并反序列化。

JSON进阶

Python的dict对象可以直接序列化为JSON的{},对于我们使用class表示对象时,我们不能直接对类的实例进行序列化,会出现TypeError错误:

import json
class Student(object):
	def __init__(self,name,age,score):
		self.name = name
		self.age = age
		self.score = score
s = Studrnt('Bob',20,90)
print(json.dumps(s))
# Traceback (most recent call last):
  ...
# TypeError: <__main__.Student object at 0x10603cc50> is not JSON serializable

json模块中的dumps()方法还提供了许多可选参数,可选参数default就是把任意一个对象变成一个可序列为JSON的对象,我们只需要为Student专门写一个转换函数,再把函数传进去即可:

def student2dict(std):
    return {
        'name': std.name,
        'age': std.age,
        'score': std.score

接下来运行:

>>> print(json.dumps(s, default=student2dict))
# {"age": 20, "name": "Bob", "score": 88}

Student实例s首先被student2dict()函数转换成dict,然后再被顺利序列化为JSON。
如果换一个类,比如Teacher类,我们就无法再用此方法进行转化,每次都编写一个转换函数太麻烦了。
通常class的实例都有一个__dict__属性,它就是一个__dict__,用来存储实例变量。也有少数例外,定义了__slots__的class就没有__dict__属性。

print(json.dumps(s, default=lambda obj: obj.__dict__))

练习
对中文进行JSON序列化时,json.dumps()提供了一个ensure_ascii参数,观察该参数对结果的影响:

>>> obj = dict(name='小明', age=20)
>>> s = json.dumps(obj, ensure_ascii=True)
>>> s
# '{"name": "\\u5c0f\\u660e", "age": 20}'
>>> obj = dict(name='小明', age=20)
>>> s = json.dumps(obj, ensure_ascii=False)
>>> s
# '{"name": "小明", "age": 20}'

由上面的运行结果可知,想输出真正的中文需要指定ensure_ascii=False,这是因为json.dumps() 序列化时对中文默认使用的ascii编码。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章