網站首頁 編程語言 正文
前面章節我們學些了文件對象的創建、寫入與讀取,并且針對 .py 文件 與 .txt 文件進行了有針對性的小練習。 通過前面的學習我們知道,文件對象的讀寫只能進行 字符串 或 byte 類型的操作,其他類型只能通過格式化存儲或者數據類型的轉換才能實現。
但無論是哪一種,從文件中讀取數據后都需要進行比較復雜的處理才能還原到原始的數據類型。為了簡化數據類型的寫入和獲取,今天我們來學習一個新的知識點 —> 序列化。
通過學習序列化,可以不必過分擔心寫入文件的數據類型是什么,并且讀取文件也可以非常輕松的還原數據類型。[比較討厭這種每章之前寫概述、摘要的短句。]
初識序列化與反序列化
什么是序列化?
通俗一點來說,序列化就是將 對象的信息 或者 數據結構的信息 通過一定的規則進行轉換,可以達到 文件存儲 或 網絡傳輸 的效果。通過前面章節的學習,我們知道如果要進行存儲或網絡傳輸,最終的數據類型都是 字符串,而且這些字符串還需要是有一定規則的字符串。
而我們今天要學習的 內置模塊 ---> json 可以用于文件存儲或者網絡傳輸,這也是序列化的作用。
而反序列化就是通過序列化規則生成的字符串再反轉為原始的數據類型,這就是反序列化。
這里我們可以引入 字符串 與 byte 之間的轉換來理解 序列化與反序列化, 字符串與 byte 類型之間互相轉換常用的 encode() 函數、與 decode() 函數,分別代表著編碼與解碼,所以有編碼,就一定有解碼 。套用在序列化來理解,既然存在序列化,那么就肯定有對應的反序列化哈。
可序列化的數據類型
哪些數據類型是可以序列化,哪些又是不可以序列化的呢?
可序列化:number、str、list、tuple、dict [字典是最常用的序列化數據類型]
不可序列化:class 、def (函數與實例化對象)、set 是無法進行序列化的
Python 中的json
json模塊是一個通用的序列化模塊,通過它可以完成通用化的序列化與反序列化操作。為什么說是通用的,那是因為幾乎所有的編程語言都有json模塊,而且他們序列化與反序列化的規則是統一的。
所以我們在 Python 中序列化的內容,在任意其他編程語言中都可以進行反序列化并使用原始的數據,這就是通用的意思。
dumps() 與 loads() 函數
json 中最重要的函數 - 就是 dumps() 與 loads() 函數
方法名 | 參數 | 介紹 | 舉例 | 返回值 |
---|---|---|---|---|
dumps | obj | 對象序列化 | json.dumps([1, 2, 3]) | 字符串 |
loads | str | 反序列化 | Json.loads(’[1, 2, 3]’) | 原始數據類型 |
可序列化數據類型演示案例
演示案例如下:
import json int_test = 666 # 定義 整型、字符串、列表、元組、字典 五種數據類型 ,用于序列化測試 str_test = 'test_string' list_test = [1, 2, 3] tuple_test = (4, 5, 6) dict_test = {'Name': '托尼.史塔克', 'Sex': '男'} int_test_json = json.dumps(int_test) # 將上文中五種數據類型進行序列化操作 str_test_json = json.dumps(str_test) list_test_json = json.dumps(list_test) tuple_test_json = json.dumps(tuple_test) dict_test_json = json.dumps(dict_test)
在 Treminal 終端 執行上述測試腳本,如下圖:
這里我們重點介紹一下 字典類型的序列化結果
In [7]: dict_test_json Out[7]: '{"Name": "\\u6258\\u5c3c.\\u53f2\\u5854\\u514b", "Sex": "\\u7537"}'
從執行結果我們可以看出字典類型的數據類型,經過序列化后。字典變成了字符串的同時,且字典內的 單引號 變成了 雙引號,中文也變成了比特類型,并且進行了 encode 。(這是序列化的一個標準)
為什么我們說 字典類型是非常是和序列化的呢?實際上 json 并不僅僅是一個標準,也是一種文件格式。比如我們編寫腳本的 .py 格式的文件,就是 python 文件容器;.txt 格式的文件是普通的文本文件容器;同樣的,.json 格式的文件也是文件容器,json 文件存儲的樣式(格式)就是字典類型的序列化格式。
接下來我們再嘗試將上文的五種測試數類型反序列化處理,看看結果會怎樣?
_int_test_json = json.loads(int_test_json) _str_test_json = json.loads(str_test_json) _list_test_json = json.loads(list_test_json) _tuple_test_json = json.loads(tuple_test_json) _dict_test_json = json.loads(dict_test_json)
在 Treminal 終端 執行上述測試腳本,如下圖:
劃重點:元組類型經過序列化處理后再通過反序列化還原數據時,會變為列表數據類型。這是因為 元組類型 是 python 語言中特有的數據類型,json 作為一個通用格式,無法識別元組類型。所以在針對元組類型進行序列化的時候,會先將 元組類型 ,先轉為 列表,再進行序列化處理;同樣的在進行反序列化處理時,就會將序列化后的 元組類型 ,又轉成了 列表類型 。(類型的轉換,不影響對數據的使用)
bool 、None 類型的序列化與反序列化
示例如下:
print(json.dumps(True)) # >>> 輸出結果:true print(json.dumps(False)) # >>> 輸出結果:false print(json.dumps(None)) # >>> 輸出結果:null
從上述運行結果來看,bool 類型經過序列化處理后,變成了小寫的 true、false;而 None 類型則變成了 小寫的 null 。
之所以會這樣,是因為在大多數的編程語言中, bool 類型都是小寫的 true、false 。json 作為一個通用的序列化模塊,也同樣遵循著這種規則。(小寫的 true、false 依然是字符串類型。 )
接下來我們再將上述的序列化處理后的 bool 、None 類型 進行反序列化處理
print(json.loads(json.dumps(None))) # >>> 輸出結果:None print(json.loads(json.dumps(True))) # >>> 輸出結果:True print(json.loads(json.dumps(False))) # >>> 輸出結果:False
從執行結果我們看到,經過反序列化之后,bool、None 類型又被還原成了 python 可讀的狀態。
Python 中的pickle
pickle模塊與json模塊一樣可以進行序列化與反序列化,區別在于 pickle 是 Python 內置的序列化模塊,而且不像 json 那么通用,它只能用于 python 自身來使用,其他語言可能就無法處理了,但pickle模塊的性能是要比 json 更好的。如果是僅僅用于 python 自身來使用,pckle 模塊還是一個挺不錯的選擇哦。
dumps() 與 loads() 函數
方法名 | 參數 | 介紹 | 舉例 | 返回值 |
---|---|---|---|---|
dumps | obj | 對象序列化 | json.dumps([1, 2, 3]) | 比特 |
loads | str | 反序列化 | Json.loads(’[1, 2, 3]’) | 原始數據類型 |
注意:區別于 json ,pickle 模塊的 dumps() 函數 返回的是 byte 類型 ,而 loads() 函數也僅支持 byte 類型的 pickle 序列進行反序列化的操作。
pickle模塊的序列化與反序列化練習
pickle模塊與json模塊的用法是完全一致的,這里我們就不過多的演示,只針對 dict 類型演示一下即可。
json 模塊 - 序列化小實戰
需求:
創建一個 test.json 的空文件。
定義一個 write 函數寫入 dict 數據類型的內容到 test.json 文件
定義一個 read 函數,將寫入到 test.json 文件的內容,反序列化讀取出來
# coding:utf-8 import json data = {'name': '托尼·史塔克', 'age': 52, 'top': 185} def read(path): # 定義 read() 函數,讀取 test.json 文件(返回對象為 反序列化后的內容) with open(path, 'r') as f: data = f.read() return json.loads(data) def write(path, data): # 定義 write() 函數,將 data 寫入到 test.json 文件 with open(path, 'w') as f: if isinstance(data, dict): # 判斷 data 是否為字典類型。不是的情況下主動拋出異常 _data = json.dumps(data) f.write(_data) else: raise TypeError('\'data\' 不是一個字典類型的數據') return True if __name__ == '__main__': write('test.json', data) result = read('test.json') print(result) result['Sex'] = 'Man' # 加入 {'Sex': 'Max'} 鍵值對 write('test.json', result) # 將加入的 鍵值對 寫入 test.json 文件 result_test_json = read('test.json') print(result_test_json)
執行結果如下:
總結:json的使用在我們的未來 工作中是非常高頻的,所以大家一定要多多練習,加以掌握。
原文鏈接:https://blog.csdn.net/weixin_42250835/article/details/123723638
相關推薦
- 2022-03-22 .NET?6開發TodoList開發查詢分頁_實用技巧
- 2022-06-11 Go1.18?新特性之多模塊Multi-Module工作區模式_Golang
- 2022-12-10 c語言如何設置隨機數及逐行解析_C 語言
- 2023-01-17 Keras中Sequential模型和Functional模型的區別及說明_python
- 2022-06-20 python中的隨機數?Random介紹_python
- 2022-09-17 利用Python實現快速批量轉換HEIC文件_python
- 2022-01-29 win server 2008 web IIS部署asp.net程序后,CSS樣式錯亂不顯示問題
- 2023-06-16 Visual?Studio?如何創建C/C++項目問題_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支