摘要:默認(rèn)情況下,它也是不安全的,如果數(shù)據(jù)是由黑客精心設(shè)計(jì)的,則反序列化的數(shù)據(jù)可能被植入惡意代碼。總結(jié)為我們提供了數(shù)據(jù)序列化的工具。如果是自己內(nèi)部使用,可以作為一個(gè)選擇進(jìn)行復(fù)雜對象的序列化。
上一節(jié)我們學(xué)習(xí)了文件的讀寫,把一個(gè)字符串(或字節(jié)對象)保存到磁盤是一件很容易的事情。但是在實(shí)際編程中,我們經(jīng)常需要保存結(jié)構(gòu)化數(shù)據(jù),比如復(fù)雜的字典、嵌套的列表等等,這時(shí)候就需要我們想辦法把這些結(jié)構(gòu)化數(shù)據(jù)先轉(zhuǎn)變成一個(gè)字符串,這個(gè)轉(zhuǎn)換過程就叫做“序列化”,這一過程的逆操作就是“反序列化”。
JSON序列化序列化數(shù)據(jù)的操作在各個(gè)語言編程中都會(huì)遇到,當(dāng)然也出現(xiàn)了標(biāo)準(zhǔn)化的格式,比如:JSON(JavaScript Object Notation)。JSON格式通常被現(xiàn)代應(yīng)用程序用于數(shù)據(jù)交換,尤其是在Web中廣為人知,是許多程序員的選擇。Python支持JSON的模塊叫做json。
JSON的數(shù)據(jù)格式和Python中的字典和列表非常相似,可以說它是字典和列表相互嵌套的結(jié)合體,而這些字典和列表的基本數(shù)據(jù)類型只能是:字符串、整數(shù)、浮點(diǎn)數(shù)、布爾型、None,不能是自定義的類等復(fù)雜對象。
一個(gè)對象x可以用一行簡單的代碼轉(zhuǎn)換成它對應(yīng)的JSON字符串:
In [124]: import json In [125]: json.dumps({"Tom": 23, "Jim": 25, "William": 21}) Out[125]: "{"Tom": 23, "Jim": 25, "William": 21}"
把JSON字符串反序列化為Python對象的代碼也只有一行:
In [126]: json.loads("{"Tom": 23, "Jim": 25, "William": 21}") Out[126]: {"Tom": 23, "Jim": 25, "William": 21}
dumps()方法有個(gè)變體叫做dump(),它是將對象序列化到文件中。如果f是一個(gè)文件對象,我們可以這樣操作:
json.dump(x, f)
對應(yīng)的,從文件對象f中反序列化的操作就是:
x = json.load(f)
dumps()函數(shù)有很多參數(shù)可選,使我們生成不同格式的JSON字符串,具體可以在IPython中通過json.dumps?來查看。我們可以通過下面的例子來了解一下:
(1)緊湊編碼
通過separators參數(shù)來實(shí)現(xiàn):
In [130]: json.dumps({"Tom": 23, "Jim": 25, "William": 21}, separators=(",", ":")) Out[130]: "{"Tom":23,"Jim":25,"William":21}"
(2)美化輸出
通過sort_keys, indent參數(shù)來實(shí)現(xiàn):
In [132]: print(json.dumps({"Tom": 23, "Jim": 25, "9":3, "3": 10}, sort_keys=True, indent=4)) { "3": 10, "9": 3, "Jim": 25, "Tom": 23 }
(3)中文編碼
參數(shù)ensure_ascii默認(rèn)為True,會(huì)把中文等非ascii字符轉(zhuǎn)義:
In [133]: print(json.dumps({"小剛": 23, "小明": 25, "9":3, "3": 10}, sort_keys=True, indent=4)) { "3": 10, "9": 3, "u5c0fu521a": 23, "u5c0fu660e": 25 } In [134]: print(json.dumps({"小剛": 23, "小明": 25, "9":3, "3": 10}, sort_keys=True, indent=4, ensure_ascii=False)) { "3": 10, "9": 3, "小剛": 23, "小明": 25 }pickle模塊序列化
與json模塊不同,pickle可以對任意復(fù)雜的Python對象進(jìn)行序列化,它是Python特有的,不能與其它語言進(jìn)行通信。默認(rèn)情況下,它也是不安全的,如果數(shù)據(jù)是由黑客精心設(shè)計(jì)的,則反序列化的數(shù)據(jù)可能被植入惡意代碼。
pickle的接口跟json是一樣的,序列化用dumps(x), dump(x, f),反序列化使用loads(s), load(f)。但是,pickle可以序列化任意復(fù)雜的對象,比如自定義的類、函數(shù)都是可以用它來序列化的。比如下面這個(gè)例子就是序列化b并反序列化一個(gè)函數(shù):
In [136]: def add(x, y): ...: print(x+y) ...: In [137]: import pickle In [138]: s = pickle.dumps(add) In [139]: s Out[139]: b"x80x03c__main__ add qx00." In [140]: f = pickle.loads(s) In [141]: f Out[141]:In [142]: f(2, 3) 5
從這個(gè)例子中,我們實(shí)現(xiàn)了序列化和反序列化一個(gè)函數(shù)的功能。這樣,我們可以把一些函數(shù)、自定義的類等各種對象先序列化到文件,然后把這個(gè)文件發(fā)給別人,別人可以通過反序列化來使用這些自定義的類和函數(shù)。這個(gè)過程中,如果有人對序列化文件做了手腳,比如通過修改文件修改了函數(shù)add()的實(shí)現(xiàn),就有可能被黑客利用來進(jìn)行攻擊。這也是前面我們?yōu)槭裁凑fpickle默認(rèn)是不安全的。所以,在選擇是否使用它進(jìn)行序列化時(shí),要先思考一番。
總結(jié)Python為我們提供了數(shù)據(jù)序列化的工具。如果需要和其它程序進(jìn)行數(shù)據(jù)交換,json是最好的選擇。如果是自己內(nèi)部使用,pickle可以作為一個(gè)選擇進(jìn)行復(fù)雜對象的序列化。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/43810.html
摘要:第二個(gè)索引元素不在分片內(nèi)。顯示操作索引指向第個(gè)元素,第個(gè)元素不存在。序列加法乘法表示個(gè)空列表空列表用初始化成員資格運(yùn)算符布爾運(yùn)算符,檢查值是否在序列中。修改列表,沒有返回值。在原位置對列表排序。 序列 例: Edward = [abc, 12] 序列中的所有元素都是有編號(hào)的,從0開始遞增。 Note: 使用負(fù)數(shù)索引-1,Python會(huì)從右邊,也就是從最后一個(gè)元素開始計(jì)數(shù)。最后一個(gè)元素...
摘要:貢獻(xiàn)者飛龍版本最近總是有人問我,把這些資料看完一遍要用多長時(shí)間,如果你一本書一本書看的話,的確要用很長時(shí)間。為了方便大家,我就把每本書的章節(jié)拆開,再按照知識(shí)點(diǎn)合并,手動(dòng)整理了這個(gè)知識(shí)樹。 Special Sponsors showImg(https://segmentfault.com/img/remote/1460000018907426?w=1760&h=200); 貢獻(xiàn)者:飛龍版...
摘要:在中,并不是一個(gè)內(nèi)置函數(shù),而是一個(gè)類型,但是在中它是一個(gè)內(nèi)置函數(shù)上面是中從看到的的說明,它的是,而不像內(nèi)置函數(shù)的是。雖然的類型從中的內(nèi)置函數(shù)變成了中的,但并不影響我們對它的使用。 循環(huán)是計(jì)算機(jī)程序中經(jīng)常用到的流程。試想一下,如果我們有一萬個(gè)數(shù)據(jù)要處理,每個(gè)數(shù)據(jù)處理的流程都一模一樣,如果我們用順序流程就要把處理流程重復(fù)寫一萬遍,是不是很累?而用for循環(huán)就簡單多了。 showImg(ht...
摘要:所解包的序列中的元素?cái)?shù)量必須和賦值符號(hào)左邊的變量數(shù)量完全一致。其中,冒號(hào)標(biāo)識(shí)語句塊開始?jí)K中每一個(gè)語句都是縮進(jìn)相同量退回到和已經(jīng)閉合的塊一樣的縮進(jìn)量時(shí),表示當(dāng)前塊結(jié)束。成員資格運(yùn)算符字符串和序列比較字符串可按照字母順序比較。 print和import print打印多個(gè)表達(dá)式,用逗號(hào),隔開 print abc:, 42, nonono #輸出在每個(gè)參數(shù)之間添加空格 print在結(jié)尾處加上...
閱讀 3485·2023-04-25 23:25
閱讀 2145·2021-11-12 10:36
閱讀 2842·2019-08-30 12:47
閱讀 2077·2019-08-29 18:45
閱讀 475·2019-08-29 17:28
閱讀 1818·2019-08-29 17:15
閱讀 1740·2019-08-29 16:05
閱讀 1453·2019-08-29 14:17