Python 序列化模塊(json,pickle,shelve) 百日築基之得氣(三)

来源:https://www.cnblogs.com/caesar-id/archive/2019/02/21/10415132.html
-Advertisement-
Play Games

json模塊 JSON (JavaScript Object Notation):是一個輕量級的數據交換格式模塊,受javascript對象文本語法啟發,但不屬於JavaScript的子集。 常用方法: dump(obj,fp):將對象以字元串的形式寫入文件中。 load(fp):將數據從文件中讀出 ...


json模塊

JSON (JavaScript Object Notation):是一個輕量級的數據交換格式模塊,受javascript對象文本語法啟發,但不屬於JavaScript的子集。

常用方法:

dump(obj,fp):將對象以字元串的形式寫入文件中。

load(fp):將數據從文件中讀出,並返回(需要變數接收)。

dumps(obj):將對象轉換成json字元串形式。

loads(str):將json字元串數據轉換成原來的數據類型。

實例如下:dumps(obj) | loads(str)

import json

dict_1 = {"電影":"黃飛鴻","電視劇":"霍元甲"}

json_str = json.dumps(dict_1)  # 將字典轉換成json的字元串類型

dict_2 = json.loads(json_str)  # 將json的字元串類型轉換成原數據

print(json_str,type(json_str))

print(dict_2.items(),type(dict_2))

# 列印內容如下
{"\u7535\u5f71": "\u9ec4\u98de\u9e3f", "\u7535\u89c6\u5267": "\u970d\u5143\u7532"} <class 'str'>
dict_items([('電影', '黃飛鴻'), ('電視劇', '霍元甲')]) <class 'dict'>

實例如下:dump(obj,fp) | load(fp)

import json
# 向文件中寫入json數據

dict_1 = {"電影":"黃飛鴻","電視劇":"霍元甲"}

file_write = open("json.txt",mode="w",encoding="utf-8")

json.dump(dict_1,file_write)  # 將字典以json的字元串類型寫入文件

file_write.close()
# 從文件中讀取json數據

file_read = open("json.txt",mode="r",encoding="utf-8")

dict_2 = json.load(file_read) # 將文件中內容轉換成原數據類型並返回

file_read.close()

print(dict_2.items(),type(dict_2)) # 列印轉換後的數據

# 列印內容如下
dict_items([('電影', '黃飛鴻'), ('電視劇', '霍元甲')]) <class 'dict'>

這裡需要註意的是json模塊dump(obj,fp)雖然可以多次上傳,但是在load時會報錯,load(fp)函數不能轉換多次dump的數據。所以如果想要向json文件中新增數據時,需要將數據load下來轉換成原數據,然後在原數據基礎上進行新增。最後將處理後的數據dump到文件中。

pickle模塊:

屬於python專有的模塊,用法,功能與json類似。

常用方法:

dump(obj,fp):將對象以字元串的形式寫入文件中。

load(fp):將數據從文件中讀出,並返回(需要變數接收)。

dumps(obj):將對象轉換成json字元串形式。

loads(str):將json字元串數據轉換成原來的數據類型。

dump(obj,fp)  |  load(fp) 示例如下;

import pickle
# 將數據以json方式寫入文件

dict_1 = {"電影":"黃飛鴻","電視劇":"霍元甲"}

file_write = open("pickle.txt",mode="wb")

pickle.dump(dict_1,file_write)  # 將字典以位元組的形式寫入文件

file_write.close()
# 從文件中以json方式讀取數據

file_read = open("pickle.txt",mode="rb")

dict_2 = pickle.load(file_read)  # 將文件中內容轉換成原數據類型並返回

file_read.close()

print(dict_2.items(),type(dict_2)) # 列印轉換後的數據

# 列印內容如下
dict_items([('電影', '黃飛鴻'), ('電視劇', '霍元甲')]) <class 'dict'>

dumps(obj)  |  loads(obj) 示例如下;

import pickle

dict_1 = {"電影":"黃飛鴻"}

pickle_byte = pickle.dumps(dict_1)  # 將字典轉換成pickle位元組

print(pickle_byte)

# 將pickle位元組轉換成原數據

dict_2 = pickle.loads(pickle_byte)

print(dict_2.items(),type(dict_2)) # 列印轉換後的數據
# 列印內容如下
b'\x80\x03}q\x00X\x06\x00\x00\x00\xe7\x94\xb5\xe5\xbd\xb1q\x01X\t\x00\x00\x00\xe9\xbb\x84\xe9\xa3\x9e\xe9\xb8\xbfq\x02s.'
dict_items([('電影', '黃飛鴻')]) <class 'dict'>

與json不同的是pickle可以多次dump多次load,如下:

import pickle

dict_1 = {"電影":"黃飛鴻"}

dict_3 = {"電視劇":"霍元甲"}

dict_5 = {"動畫片":"葫蘆娃"}

file_write = open("pickle.txt",mode="wb")

pickle.dump(dict_1,file_write)  # 將dict_1以位元組的形式寫入文件

pickle.dump(dict_3,file_write)  # 將dict_3以位元組的形式寫入文件

pickle.dump(dict_5,file_write)  # 將dict_5以位元組的形式寫入文件

file_write.close()

file_read = open("pickle.txt",mode="rb")

dict_2 = pickle.load(file_read)  # 將文件中內容轉換成原數據類型並返回

dict_4 = pickle.load(file_read)  # 將文件中內容轉換成原數據類型並返回

dict_6 = pickle.load(file_read)  # 將文件中內容轉換成原數據類型並返回

file_read.close()

print(dict_2.items(),type(dict_2)) # 列印轉換後的數據

print(dict_4.items(),type(dict_4)) # 列印轉換後的數據

print(dict_6.items(),type(dict_4)) # 列印轉換後的數據
# 列印內容如下
dict_items([('電影', '黃飛鴻')]) <class 'dict'>
dict_items([('電視劇', '霍元甲')]) <class 'dict'>
dict_items([('動畫片', '葫蘆娃')]) <class 'dict'>

小結:

1、json屬於通用的模塊,Java,JS等其它語言也支持。

     pickle是Python私有的,只支持Python。

2、json將對象轉換成json字元串類型。

     pickle將對象轉換成pickle位元組類型。

3、json只能轉換dict,list,tuple,str,int,float,bool值等簡單數據類型

     pickle能轉換除了lamda以外的所有已知數據類型。

4、json雖然可以多次dump但是load會報錯(這是最大的傷)。

     pickle可以多次dump,多次load。

shelve模塊

使用json或者pickle持久化數據,能dump多次,但load的話只能取到最新的dump, 因為先前的數據已經被後面dump的數據覆蓋掉了。如果想要實現dump多次不被覆蓋,就可以想到使用shelve模塊。shelve模塊可以持久化所有pickle所支持的數據類型。另外,寫程式的時候如果不想用關係資料庫那種重量級的去存儲數據,也可以用到shelve。

shelve是用key來訪問的,使用起來和字典類似。 要註意的是,在shelve模塊中,key必須為字元串,而值可以是python所支持的數據類型。

另外,shelve其實用anydbm去創建DB並且管理持久化對象的。

shelve只提供給我們一個open方法,是用key來訪問的,使用起來和字典類似。 可以像字典一樣使用get來獲取數據等。

如下操作:

import shelve

f_shelve = shelve.open('shelve') # 創建一個文件句柄

f_shelve["name"] = "小明" # 向文件中存放數據

f_shelve["age"] = 21 # 向文件中存放數據

f_shelve["sex"] = ""

運行後會生成3個文件:shelve.bak shelve.dat shelve.dir

shelve.dat 存儲的就是b位元組數據類型的數據。bak和dir尾碼從字面上看是備份和目錄,具體做什麼的不是很清楚。

當我們寫好數據後,如何讀取呢?

import shelve

f_shelve = shelve.open('shelve') # 創建一個文件句柄

# 列印文件內容,和類型

print(f_shelve["name"],f_shelve["age"],f_shelve["sex"],type(f_shelve))

# 列印內容如下
小明 21 男 <class 'shelve.DbfilenameShelf'>

既然f_shelve類似於字典,那我們也可以使用for迴圈進行列印,如下:

import shelve

f_shelve = shelve.open('shelve') # 創建一個文件句柄

# 使用for迴圈列印內容

for k,v in f_shelve.items():

    print(k,v)

# 列印內容如下
name 小明
age 21
sex 男

f_shelve現在是一個特殊的文件句柄,它可以執行字典的多數方法,對文件里的數據進行操作。

import shelve

f_shelve = shelve.open('shelve') # 創建一個文件句柄

f_shelve["list"] = [1,2,3]  # 向文件中添加數據列表

f_shelve["list"].append("abc") # 向列表中追加內容.

f_shelve["list"].pop(1) # 從列表中刪除一個元素



f_shelve["name"] = "小明" # 向文件中追加內容

f_shelve["name"] = "小紅" # 修改name所對應的值

print(f_shelve["list"],f_shelve["name"],sep="\n")

# 列印內容如下
[1, 2, 3]
小紅

通過上面的列印內容我們可以發現,我們將列表寫入文件後,然後在讀取出來進行追加和刪除元素,並沒有對文件產生影響,文件中的列表內容還是原來的值。而我們向文件中添加字元串時,在讀取出來對字元串進行修改發現數據被修改了。

由此我們可以知道在向文件中寫入一個可變的數據時,如果讀取出來對數據進行修改只是在記憶體中的修改,修改後的數據並沒有被真正寫入到文件中。那麼我們該如何進行操作呢?這時就需要回寫了。

import shelve

# 創建一個特殊的文件句柄,並添加回寫功能

f_shelve = shelve.open('shelve',writeback=True)

f_shelve["list"] = [1,2,3]  # 向文件中添加數據列表

f_shelve["list"].append("abc") # 向列表中追加內容.

f_shelve["list"].pop(1) # 從列表中刪除一個元素

print(f_shelve["list"])

# 列印內容如下
[1, 3, 'abc']

這回我們在修改列表時,可以看出列表的數據確實被修改了。

總結如下:

1、shelve模塊將記憶體數據以字典的類型(key,value)通過文件持久化,模擬出簡單的db效果。

2、shelve模塊可以持久化任何pickle所支持的python數據格式,但是它的key必需得是字元串。

3、shelve可以看作是pickle模塊的一個封裝,但它實現了可以多次dump(後面的dump不會覆蓋前面的)和多次load。

4、shelve訪問己有key時,實際上取出的是數據源給出的一份拷貝,所以對於拷貝做出的增加和刪除等操作都需要用writeback=True參數才能實現寫入迴文件中進行修改。

5、shelve對於d[key] = data這種操作,視為存儲數據,無則新增,有則覆蓋,

對與訪問key當中的值(條目)進行修改,預設不回寫並不矛盾和衝突。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一個項目里只能有一個main函數, 如果出現 error:LNK2005 的錯誤,那麼需要檢查你是不是有兩個源代碼文件中都定義了main函數。 例如: 如果在a.cpp中定義了main函數,在b.cpp中也定義main函數,編譯執行就會報 error:LNK2005 的錯誤。 ...
  • 一、 lucene簡介 1. Lucene Lucene是apache下的一個開源的全文檢索引擎工具包。它為軟體開發人員提供一個簡單易用的工具包(類庫),以方便的在目標系統中實現全文檢索的功能。 官網: http://lucene.apache.org/ 2. 全文檢索 全文檢索是指電腦索引程式通 ...
  • 前面介紹了Lambda表達式的用法,從實踐中發現它確實極大地方便了開發者,然而不管是匿名內部類還是Lambda表達式,所舉的例子都離不開各類數組的排序方法,倘使Lambda表達式僅能用於sort方法,無疑限制了它的應用範圍。那麼除了sort方法,還有哪些場景能夠將Lambda表達式派上用場呢?既然匿 ...
  • 類可以允許其他類或者函數訪問他的非公有成員,方法是令其他類或者函數成為他的友元(friend)。 友元的聲明: 友元聲明只能出現在類的內部,但是在類內出現的具體位置不限;由於友元不是類的成員,所以不受所在區域訪問控制級別的約束。 友元的聲明並非傳統意義上的聲明,所以為了能夠正確的調用該友元函數,還須 ...
  • 輸出結果: ...
  • 題意 "題目鏈接" Sol 神仙題Orz 首先不難看出如果我們從$a_i$向$i$連一條邊,我們會得到以$0$為根的樹(因為每個點一定都有一個入度,出現環說明無解),同時在進行排列的時候需要保證父親節點一定在孩子節點之前出現 接下來考慮直接貪心。對於某些權值很小的點,我們需要讓其儘早出現,同時又要滿 ...
  • 假定一個全英文的文件,讀取該文件,請統計多少個不重覆的單詞,並且在另外一個文件中寫上結果每個單詞出現的次數,以及一共有多少個不重覆的單詞分別為哪些 註意:文件中可能包含特殊符號 Step1:打開文件,可使用方法如下: 方法1:fp = open(file,'r',encoding ='utf-8') ...
  • 題意 "題目鏈接" Sol 神仙題Orz Orz zbq爆搜70。。 考慮"與"和"或"的性質 $0 \& 0 = 0, 1 \& 0 = 0$ $0 \mid 1 = 1, 1 \mid 1 = 1$ 也就是說某一個數$\& 0$之後不管之前是什麼,現在的值變為$0$ 某一個數$\mid 1$之後 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...