您好,登錄后才能下訂單哦!
這篇文章主要講解了“如何理解Python對象序列化與反序列化”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何理解Python對象序列化與反序列化”吧!
引言
pickle
json
尾語
將對象的狀態信息轉換為可以存儲或傳輸的形式的過程叫作序列化
類似地從序列化后的數據轉換成相對應的對象叫作 反序列化
本文介紹 Python
將對象序列化和反序化的兩個模塊
picklejson
pickle
# 序列化 In [19]: num = 66 In [20]: s = 'python' In [21]: pi = 3.14 In [22]: li = [1, 2, 3] In [27]: b_num = pickle.dumps(num) In [28]: b_s = pickle.dumps(s) In [29]: b_pi = pickle.dumps(pi) In [30]: b_li = pickle.dumps(li) In [31]: b_num Out[31]: b'\x80\x03KB.' In [32]: b_s Out[32]: b'\x80\x03X\x06\x00\x00\x00pythonq\x00.' In [33]: b_pi Out[33]: b'\x80\x03G@\t\x1e\xb8Q\xeb\x85\x1f.' In [34]: b_li Out[34]: b'\x80\x03]q\x00(K\x01K\x02K\x03e.' In [35]: type(b_li) Out[35]: bytes # 反序列化 In [47]: pickle.loads(b_num) Out[47]: 66 In [48]: pickle.loads(b_s) Out[48]: 'python' In [49]: pickle.loads(b_pi) Out[49]: 3.14 In [50]: li = pickle.loads(b_li) In [51]: li Out[51]: [1, 2, 3] In [52]: type(li) Out[52]: list
自定義的對象也能序列化
class User: def __init__(self, name, sex): self.name = name self.sex = sex In [38]: user = User('hui', '男') In [39]: b_user = pickle.dumps(user) In [40]: b_user Out[40]: b'\x80\x03c__main__\nUser\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00huiq\x04X\x03\x00\x00\x00sexq\x05X\x03\x00\x00\x00\xe7\x94\xb7q\x06ub.' In [41]: type(b_user) Out[41]: bytes In [42]: user = pickle.loads(b_user) In [43]: type(user) Out[43]: __main__.User In [44]: user.name Out[44]: 'hui' In [45]: user.sex Out[45]: '男'
注意:pickle
序列化后數據都是字節(bytes)類型
pickle
也可以把對象序列化保存到文件,然后從文件反序化回對象。
import pickle class User: def __init__(self, name, sex): self.name = name self.sex = sex user = User('ithui', '男') f = open('user.txt', mode='wb') pickle.dump(user, f) f.close()
從文件反序化回對象
In [3]: f = open('user.txt', 'rb') ...: user = pickle.load(f) ...: f.close() ...: In [4]: user Out[4]: <__main__.User at 0x16c58ebef08> In [5]: user.name Out[5]: 'ithui' In [6]: user.sex Out[6]: '男'
pickle
模塊雖然可以將對象序列化,但它只適用于 Python
語言,所以不方便數據交換。例如你將數據發給前端,js
則無法將數據轉成自己想要的。
如果我們要在不同的編程語言之間傳遞對象,就必須把對象序列化為標準格式,比如 json
,因為 json
表示出來就是一個字符串,可以被所有語言讀取,也可以方便地存儲到磁盤或者通過網絡傳輸進行數據交換。
json
字符串表示的對象就是 js
的對象,json
和 Python
內置的數據類型對應如下:
JSON類型 | Python類型 |
---|---|
{} | dict |
[] | list |
"string" | 'str' 或 u'unicode' |
3.14 | int 或 float |
true / false | True / False |
null | None |
In [7]: import json In [8]: info_dict = { ...: 'name': 'hui', ...: 'age': 22, ...: 'is_admin': True, ...: 'hobbies': ['下象棋', '寫代碼'], ...: 'other': None ...: } In [9]: info_json = json.dumps(info_dict) In [10]: info_json Out[10]: '{ "name": "hui", "age": 22, "is_admin": true, "hobbies": ["\\u4e0b\\u8c61\\u68cb", "\\u5199\\u4ee3\\u7801"], "other": null }' # 對應的反序列化 In [16]: info_d = json.loads(info_json) In [17]: info_d Out[17]: {'name': 'hui', 'age': 22, 'is_admin': True, 'hobbies': ['下象棋', '寫代碼'], 'other': None} In [18]: type(info_d) Out[18]: dict
看看自定義的類對象能不能 json
序列化
In [21]: import json In [22]: class User: ...: ...: def __init__(self, name, sex): ...: self.name = name ...: self.sex = sex ...: In [23]: user = User('ithui', '男') In [24]: json.dumps(user) TypeError: Object of type User is not JSON serializable
報錯了,說 User
對象不能 json
序列化。有沒有方法可以讓自定義的對象可以轉成 json
,肯定是有的。
大致思路就是先把User對象轉成可以被 json
序列化的對象,例如 dict
等,然后再把可序列化的對象給 json
模塊。
In [28]: def user2dict(obj): ...: return {'name': obj.name, 'sex': obj.sex} ...: ...: In [29]: user = User('ithui', '男') In [30]: user_dict = user2dict(user) In [31]: user_dict Out[31]: {'name': 'ithui', 'sex': '男'} In [32]: user_json = json.dumps(user_dict) In [33]: user_json Out[33]: '{"name": "ithui", "sex": "\\u7537"}'
也可以在序列化的時候指定一個轉換器,可選參數 default
就是把任意一個對象變成一個可序列為JSON的對象,我們只需要為 User
專門寫一個轉換函數,再把函數傳進去即可:
In [28]: def user2dict(obj): ...: return {'name': obj.name, 'sex': obj.sex} ...: ...: In [34]: user_json = json.dumps(user, default=user2dict) In [35]: user_json Out[35]: '{"name": "ithui", "sex": "\\u7537"}'
這樣雖然可以把自定義的類對象轉換成 json
但是要為不同的類專門定制不同的轉換器,重復又麻煩,因此想到利用的每個類的 __dict__
屬性來序列化,它是一個 dict
對象,用來存儲實例變量。也有少數例外,比如定義了 __slots__
的 class
In [36]: user.__dict__ Out[36]: {'name': 'ithui', 'sex': '男'} In [41]: json.dumps(user.__dict__) Out[41]: '{"name": "ithui", "sex": "\\u7537"}'
注意:如果是對象中的屬性又嵌套另一個不能直接 json
序列化的對象,使用 __dict__
屬性照樣無法正常序列化。
感謝各位的閱讀,以上就是“如何理解Python對象序列化與反序列化”的內容了,經過本文的學習后,相信大家對如何理解Python對象序列化與反序列化這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。