(十四)json、pickle与shelve模块
任何語言,都有自己的數(shù)據(jù)類型,那么不同的語言怎么找到一個通用的標準?
比如,后端用Python寫的,前端是js,那么后端如果傳一個dic字典給前端,前端肯定不認。
所以就有了序列化這個概念。
什么是序列化?
我們把對象(變量)從內(nèi)存中變成可存儲或傳輸?shù)倪^程稱之為序列化,在Python中叫pickling。
序列化之后,就可以把序列化后的內(nèi)容寫入磁盤,或者通過網(wǎng)絡(luò)傳輸進行前后端交互。
反過來,把變量內(nèi)容從序列化的對象重新讀到內(nèi)存里稱之為反序列化,即unpickling。
json、pickle模板都可以實現(xiàn)序列化和反序列化,而我們知道的eval則是反序列化。
?
json.dumps():將Python對象通通轉(zhuǎn)為字符串
import json a = 11 #---->'11' s = 'hello' #---->"hello"------>'"hello"' l = [1,2] #---->'[1,2]' dic = {'name':'nick'} #---->{"name":"nick"}----->'{"name":"nick"}'print(json.dumps(a)) print(json.dumps(s)) print(json.dumps(l)) print(json.dumps(dic))結(jié)果:
11? ? ? ? ? ? ? ? ? ? ? ? #這四個結(jié)果都是字符串
"hello"
[1, 2]
{"name": "nick"}
json.dumps()實際干的兩件事:
1.把這個數(shù)據(jù)中的所有的單引號變?yōu)殡p引號(有單引號就改為雙引號,沒有就不動)
2.把這個數(shù)據(jù)變?yōu)樽址?#xff08;在最外面加一對單引號)
json.loads():將字符串轉(zhuǎn)為Python對象(與eval相似)
所以,用json現(xiàn)實文件存儲:
import jsondic = {'name':'nick'} str_dic = json.dumps(dic) #轉(zhuǎn)為字符串 f_write = open('123.txt','w') f_write.write(str_dic)f_read = open('123.txt','r') data = f_read.read() data = json.loads(data) #轉(zhuǎn)回字典 print(type(data)) print(data)結(jié)果:
<class 'dict'>
{'name': 'nick'}
?json
如果我們要在不同的編程語言之間傳遞對象,就必須把對象序列化為標準格式,比如XML,但更好的方法是序列化為JSON,因為JSON表示出來就是一個字符串,可以被所有語言讀取,也可以方便地存儲到磁盤或者通過網(wǎng)絡(luò)傳輸。JSON不僅是標準格式,并且比XML更快,而且可以直接在Web頁面中讀取,非常方便。
注意,只有符合json標準格式規(guī)范的字符串,才能被解析。在字符串中,json只認雙引號,如下
123.txt: {"name": "nick"} with open('123.txt','r') as f_read:res = f_read.read()res = json.loads(res)print(type(res))print(res)結(jié)果:<class 'dict'>{'name': 'nick'}123.txt: {'name': "nick"} #單引號不符合json的標準格式with open('123.txt','r') as f_read:res = f_read.read()res = json.loads(res)print(type(res))print(res)結(jié)果:報錯pickle
pickle和json的用法幾乎一樣,只是json是將Python對象轉(zhuǎn)為字符串去存儲或傳輸,而pickle是將Python對象轉(zhuǎn)為字節(jié)去存儲或傳輸,所以pickle適用的數(shù)據(jù)類型更多,比如類、對象。但是這樣的需求場景很少,所以一般來說,我們還是用json。
用pickle現(xiàn)實文件存儲:
import pickle dic = {'name':'nick'} byte_dic = pickle.dumps(dic) print(byte_dic) with open('aaa.txt','wb') as f_write: #由于是byte,所以這里要+bf_write.write(byte_dic)with open('aaa.txt','rb') as f_read:date = f_read.read()print(type(date))date = pickle.loads(date)print(type(date))print(date)結(jié)果:
b'\x80\x03}q\x00X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00nickq\x02s.'
<class 'bytes'>
<class 'dict'>
{'name': 'nick'}
用eval內(nèi)置方法可以將一個字符串轉(zhuǎn)成python對象
用eval現(xiàn)實文件存儲:
dic = {'name':'nick','age':20} f_write = open('123.txt','w') f_write.write(str(dic)) #寫入時直接f_write.write(dic)是報錯的,必須轉(zhuǎn)為strf_read = open('123.txt','r') data = f_read.read() print(type(data)) #讀取是字符串 data = eval(data) #eval轉(zhuǎn)為字典 print(type(data)) print(data)結(jié)果:
<class 'str'>
<class 'dict'>
{'age': 20, 'name': 'nick'}
不過,eval方法是有局限性的,對于普通的數(shù)據(jù)類型,json.loads和eval都能用,但遇到特殊類型的時候,eval就不管用了,所以就要用json。
用json.dumps()將字典轉(zhuǎn)為字符串是序列化,用json.loads()將字符串轉(zhuǎn)回字典是反序列化
用pickle.dumps()將字典轉(zhuǎn)為字節(jié)是序列化,用pickle.loads()將字節(jié)轉(zhuǎn)回字典是反序列化
用str()將字典轉(zhuǎn)為字符串是序列化,用eval()將字符串轉(zhuǎn)為字典也是反序列化
shelve
最后,簡單了解一下shelve模板,shelve和json、pickle屬于同一類,也是用于數(shù)據(jù)存儲和傳輸。
shelve是將pickle模板再進一步封裝,目的就是方便我們使用,可以直接把文件當做一個字典來讀和寫,也就是直接操作鍵值對
?shelve模塊只有一個open函數(shù),返回類似字典的對象,可讀可寫;key必須為字符串,而值可以是python所支持的數(shù)據(jù)類型
import shelve #寫 f = shelve.open(r'abc.txt') #返回一個類似字典的文件對象 f['name'] = 'nick' #插入鍵值對 f['info'] = {'age':20,'num':123321} #value是一個字典 f.close()f = shelve.open(r'abc.txt') #讀 print(f['info']['age']) #直接當做一個字典來讀,二級字典 print(f['name'])?
轉(zhuǎn)載于:https://www.cnblogs.com/xulan0922/p/10204034.html
總結(jié)
以上是生活随笔為你收集整理的(十四)json、pickle与shelve模块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP 判断数据类型
- 下一篇: 乐山苏稽国防学校地址在哪里