咱們把變量從內存中變成可存儲或傳輸的過程稱之爲序列化,在Python中叫pickling,在其餘語言中也被稱之爲serialization,marshalling,flattening等等,都是一個意思。
編程
序列化以後,就能夠把序列化後的內容寫入磁盤,或者經過網絡傳輸到別的機器上。json
序列化以後,就能夠把序列化後的內容寫入磁盤,或者經過網絡傳輸到別的機器上。網絡
Python提供了pickle
模塊來實現序列化。編程語言
import pickle
ide
d = {"name":"Alice","age":22,"score":88}
函數
pickle.dumps(d)
編碼
pickle.dumps()方法能夠把任意的對象序列化成一個bytes,而後這個bytes就能夠寫入文件,也能夠用pickle.dump()方法直接把對象序列化後寫入一個文件對象
spa
with open("dump.txt","wb") as f:
code
pickle.dump(d,f)
對象
一樣咱們把對象從磁盤讀到內存時,能夠先把內容讀到一個bytes,而後用pickle.loads()方法反序列化出對象,也能夠用pickle.load()方法從一個文件對象中直接反序列化出對象。
with open("dump.txt","rb")as f:
d = pickle.load(f)
print(d)
Pickle的問題和全部其餘編程語言特有的序列化問題同樣,就是它只能用於Python,而且可能不一樣版本的Python彼此都不兼容,所以,只能用Pickle保存那些不重要的數據,不能成功地反序列化也不要緊。
=====================================正文=================================================
若是咱們要在不一樣的編程語言之間傳遞對象,就必須把對象序列化爲標準格式,好比XML,但更好的方法是序列化爲JSON,由於JSON表示出來就是一個字符串,能夠被全部語言讀取,也能夠方便地存儲到磁盤或者經過網絡傳輸。JSON不只是標準格式,而且比XML更快,並且能夠直接在Web頁面中讀取,很是方便。
Python內置的json模塊提供了很是完善的Python對象到JSON格式的轉換。
import json
d = {"name":"Bob","age":22,"score":88}
json.dumps(d)
json.dumps()方法返回了str,就是標準的JSON。相似的,dump()方法能夠直接把JSON寫入一個文件對象
with open("json.txt","w",encoding="utf-8") as f:
json.dump(d,f)
一樣要把JSON反序列化爲Python對象,用loads或對應的load方法,前者把JSON的字符串反序列化,後者從文件對象中讀取字符串並反序列化
with open("json.txt","r")as f:
d = json.load(f)
print(d)
因爲JSON標準規定JSON編碼是UTF-8,因此咱們老是能正確地在Python的str與JSON的字符串之間轉換。
==========================JSON進階=============================
Python的dict對象能夠直接序列化爲JSON的{},不過不少時候,咱們更喜歡用class表示對象,好比定義一個Student類,而後序列化
class Student(object):
def __init__(self,name,age,score):
self.name = name
self.age = age
self.score = score
s = Student("Bob",22,88)
print(json.dumps(s))
運行代碼將會獲得一個TypeError,緣由是否是一個可序列化爲JSON的對象
咱們仔細看看dumps方法的參數列表,能夠發現,除了第一個必須的obj參數外,dumps方法還提供了一大堆的可選參數,其中default參數就是把任意一個對象變爲可序列化爲JSON的對象,只須要爲Student類專門寫一個轉化函數,再把函數傳進去便可。
def student2dict(std):
return {
"name":std.name,
"age":std.age,
"score":std.score
}
這樣,Student實例首先被student2dict函數轉化爲dict,而後再被序列化爲JSON
print(json.dumps(s,default=student2dict))
下次遇到別的類的實例一樣也沒法序列化爲JSON,這個時候咱們能夠用class實例的__dict__屬性把任意的class實例變爲dict:
print(json.dumps(s,default=lambda obj: obj.__dict__))
由於一般class實例都有一個都有一個__dict__屬性,它就是一個dict,用來儲存實例變量,也有少數例外,好比定義了__slots__的class。
若是咱們要把JSON反序列化爲一個Student對象實例,只要用json.loads()方法便可:
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str))