關於python數據序列化的那些坑


                                                                                 -----世界上本來沒那么多坑,python更新到3以后坑就多了

      無論哪一門語言開發,都離不了數據儲存與解析,除了跨平台性極好的xml和json之外,python要提到的還有自身最常用pickle模塊。在使用上,python的常用模塊接口漂亮而簡單,而且json跟pickle二者使用一模一樣。首先來看一下用法,代碼如下:

import json,pickle #導入模塊。
data = {
    'name' : "lixin",
    'sex' :"female",
    'height':1.58,
    'weight':82,
    'utterance':'奏是這么瘦,來打我啊'
}
jsondata = json.dumps(data) #轉json數據
pythondata1 = json.loads(jsondata) #json數據轉python
print(pythondata1)
pickledate = pickle.dumps(data)#轉持久化數據
pythondata2 = pickle.loads(pickledate)#轉回python
print(pythondata2)

  

      以上代碼,在python3.5里運行無誤,utf-8編碼漢字可識別。然而,大多數時候,數據的解析不僅僅是使用,更多的是為了儲存。無關聯型大多儲存形式是以文本儲存,因此我們需要把數據寫入文本。python的常規文本寫入是只支持字符串的,json和pickle在寫入文本都有自己的方法接口,和普通數據轉換接口也極好區分,去掉末尾的s即可。代碼如下:

with open("jsondata.json","w") as file: #打開一個名為jsondata.json文本,只能寫入狀態 如果沒有就創建 
    json.dump(data,file) #data轉換為json數據格式並寫入文件
    file.close()#關閉文件
with open("jsondata.json","r") as file:#打開文本讀取狀態
    l =  json.load(file) #解析讀到的文本內容 轉為python數據 以一個變量接收
    print(l) #打印變量
    file.close() #關閉文件

  pickle的使用方式基本一樣只是寫入的文本格式為txt或者pk。當然json也可以直接寫入txt。以上代碼在python3.5運行無誤(不排除人品不好)。看起來簡潔方便,似乎毫無難點,那么來愉快的談一下使用中常見的坑

不管你要讀什么,反正我一點數據也沒有:

Traceback (most recent call last):
  File "/Users/penglong/Documents/python/s10/day3/test.py", line 13, in <module>
    l =  json.load(file)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/__init__.py", line 268, in load
    parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

  報錯如上,原因十分明顯,json沒有內容可解析,一般直接從文件中進行排除,會發現讀取的文本是空白,也就是說在寫入數據的時候就已經發生了錯誤。但代碼並沒有報錯,如果沒有進行寫入檢測的話,差不多就卡這了,這個原因很簡單,大部分是因為在寫入時候調用的接口是dumps而不是dump,程序本身可以編譯通過,但實際上沒有文本寫入。導致讀取的時候直接報錯。如果遇到這個問題,去排查一下寫入數據時調用的接口。

不管你要我寫什么,反正我就是寫不進去:

  File "/Users/penglong/Documents/python/s10/day3/test.py", line 17, in <module>
    pickle.dump(data,file)
TypeError: write() argument must be str, not bytes

  報錯如上,此錯誤針對pickle寫入,原因也很明顯,寫入必須是字符串,我猜json不報錯的原因很大程度是因為它長的比較像字符串。。忽略這個不靠譜的想法。這個引發的錯誤留給下一個。解決代碼如下:(ps:在2.7里面敲是沒遇到這個毛病的,在3.5里面一定要在"wb"狀態下才能正常寫入。)

with open("pickle.pk","wb") as file: #改參數"w"為"wb" 代表二進制寫入
    pickle.dump(data,file)
    file.close()

     以上,json的錯誤完全相反,可能報錯為TypeError: a bytes-like object is required, not 'str',完全不用舉例了,是踩進了pickle的坑里,直接把"wb"狀態改回"w"即可解決。然而總有那么些時候並不在意強扭的瓜甜不甜,僅僅是想強行把它給扭下來。假如犯了強迫症,一定要在wb的狀態下使用,那么,解決代碼如下:(ps:嚴重不推薦使用。。其實就是我半天不知道毛病在哪,頭痛醫頭腳痛醫腳,不管原因,強行把它給寫進去了,雖然運行和結果都沒錯,但肯定有什么地方不對)

with open("jsondata.json","wb") as file:
    file.write((json.dumps(data).encode("utf-8")))#強制以utf-8轉一下byte數據再以普通形式寫入 。
    file.close() 

不管你要做什么,反正我就是沒有函數存在:

Traceback (most recent call last):
  File "/Users/penglong/Documents/python/s10/day3/test.py", line 10, in <module>
    json.dumps(data,file)
AttributeError: module 'json' has no attribute 'dumps'

  報錯如上,json沒有dumps模塊存在。排查本地文件,大部分原因是本地文件有了json.py。python的包導入直接先導入了同級目錄下的文件。如果本地文件並沒有重復,那么就只能排查安裝文件了,python命令行編輯模式下help(json.py) 如果文件存在,可以看到其詳細信息和存放位置。但安裝文件丟失的情況,我並未遇到。踩到的坑是本地文件重復,反而在安裝文件排查了好久。 

     其實還遇到好幾個,可等熟悉了想要故意掉坑里,卻進不去了。大概,在沒有走的夠遠之前路上都是坑。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM