序列化和反序列化
程序中的對象,如Python中的字典、列表、函數、類等,都是存在內存中的,一旦斷電就會消失,不方便傳遞或存儲,所以我們需要將內存中的對象轉化為文本或者文件格式,來滿足傳輸和持久化(存儲)需求
- 序列化: 內存對象 -> 文本/文件
- 反序列化: 文本 -> 內存對象
對象在HTTP中的傳輸過程
HTTP協議是超文本傳輸協議,是通過文本或二進制進行傳輸的,所以我們發送的請求要轉化成文本進行傳輸,收到的響應也是文本格式,如果是JSON,一般還需要將文本格式重新轉化為對象
JSON對象(Python字典) -> 轉為文本請求 -> 發送請求
-> 服務器收到文本請求 -> 將文本請求轉化為對象,獲取其中的參數,處理業務
-> 返回文本格式的響應 -> 客戶端轉為對象格式來從響應中取值
JSON對象與Python字典的區別
JSON對象是javascript object即javascript中的對象,是一種通用的格式,格式嚴格,不支持備注。
JSON文本和JSON對象的區別:
- JSON文本是符合JSON格式的文本,實際上是一個字符串
- JSON對象是內存中一個對象,擁有屬性和方法,可以通過對象獲取其中的參數信息
Python中我們一般提到JSON對象指的是字典
Python的字典的格式和JSON格式,稍有不同:
- 字典中的引號支持單引號和雙引號,JSON格式只支持雙引號
- 字典中的True/False首字母大寫,JSON格式為true/false
- 字典中的空值為None, JSON格式為null
JSON格式操作方法
- 序列化(字典 -> 文本/文件句柄): json.dumps()/json.dump()
- 反序列化(文本/文件句柄 -> 字典) : json.loads()/json.load()
import json # 需要導入JSON包 data = {'name': '張三', 'password': '123456', "male": True, "money": None} # 字典格式 str_data = json.dumps(data) # 序列化,轉化為合法的JSON文本(方便HTTP傳輸) print(str_data)
輸出:{"name": "\u5f20\u4e09", "password": "123456", "male": true, "money": null}
json.dumps()支持將json文本格式化輸出
import requests import json res = requests.post("http://www.tuling123.com/openapi/api?key=ec961279f453459b9248f0aeb6600bbe&info=怎么又是你") print(res.text) # 輸出為一行文本 res_dict = res.json() # 將響應轉為json對象(字典)等同於`json.loads(res.text)` print(json.dumps(res_dict, indent=2, sort_keys=True, ensure_ascii=False)) # 重新轉為文本
看一下輸出結果對比:
{"code":100000,"text":"我才要說怎么又是你"} # res.text,有些接口中文會返回為\u.. { "code": 100000, "text": "我才要說怎么又是你" # 樹狀格式,比較清晰,顯示中文 }
- indent: 縮進空格數,indent=0輸出為一行
- sork_keys=True: 將json結果的key按ascii碼排序
- ensure_ascii=Fasle: 不確保ascii碼,如果返回格式為utf-8包含中文,不轉化為\u...
反序列化
import json
res_text = {"name": "\u5f20\u4e09", "password": "123456", "male": true, "money": null} # JSON文本格式的響應信息 res_dict = json.loads(res_text) # 轉化為字典 print(res_dict['name']) # 方便獲取其中的參數值
輸出:張三
文件的序列化與反序列化
- 序列化:字典 -> 文件句柄
import json res_dict = {'name': '張三', 'password': '123456', "male": True, "money": None} # 字典格式 f = open("demo1.json","w") json.dump(res_dict, f)
查看同級目錄,增加了一個demo1.json文件,內容為:
{"name": "\u5f20\u4e09", "password": "123456", "male": true, "money": null}
- 序列化: 文件句柄 -> 字典
在項目中(和下面腳本文件同一路徑下)新建demo2.json
文件,內容如下,保存
{
"name": "張三", "password": "123456", "male": true, "money": null }
新建Python文件
import json f = open("demo.JSON","r", encoding="utf-8") # 文件中有中文需要指定編碼 f_dict = json.load(f) # 反序列化將文件句柄轉化為字典 print(f['name']) # 讀取其中參數 f.close()
什么時候使用JSON對象(字典)什么時候使用JSON文本?
一般在組裝data參數時,建議使用字典格式,發送請求時用json.dumps(data)
轉化為文本發送,收到請求后使用json.loads(res.text)
轉化為字典,方便我們獲取其中的參數信息
練習:
- 解析以下json格式文件,發送請求並打印響應
注: method支持get和post,如果沒有method,有data默認發post請求,沒有data默認發get請求,type支持:form或json,沒有默認發form格式
demo1.json
{
"url": "http://www.tuling123.com/openapi/api", "method": "get", "params": { "key": "ec961279f453459b9248f0aeb6600bbe", "info": "你好" } }
demo2.json
{
"url": "http://openapi.tuling123.com/openapi/api/v2", "method": "post", "type": "json", "data": { "reqType": 0, "perception": { "inputText": { "text": "附近的酒店" }, "inputImage": { "url": "imageUrl" }, "selfInfo": { "location": { "city": "北京", "province": "北京", "street": "信息路" } } }, "userInfo": { "apiKey": "ec961279f453459b9248f0aeb6600bbe", "userId": "206379" } } }
作者:韓志超
鏈接:https://www.jianshu.com/p/e94a18950a53
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。