1. 程式人生 > >Python學習筆記__9.4章 序列化

Python學習筆記__9.4章 序列化

編程語言 Python

# 這是學習廖雪峰老師python教程的學習筆記

1、概覽

在程序運行的過程中,所有的變量都是在內存中。但是一旦程序結束,變量所占用的內存就被操作系統全部回收。而如果要保存變量的修改,我們就可以用序列化。

我們把變量從內存中變成可存儲或傳輸的過程稱之為序列化在Python中叫pickling

序列化之後,就可以把序列化後的內容寫入磁盤,或者通過網絡傳輸到別的機器上

反過來,把變量內容從序列化的對象重新讀到內存裏稱之為反序列化,即unpickling。

2pickle模塊

Python提供了pickle模塊來實現序列化 和 反序列化

1、序列化

d = dict(name='Bob', age=20, score=88)

# 定義一個字典

# pickle.dumps()——將對象序列化為bytes,並打印出來,需要手動寫入文件

>>> import pickle # 導入pickle模塊

>>> pickle.dumps(d) # 將對象序列化成一個bytes

b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'

# pickle.dump()——將序列化的信息直接寫入file-like Object,不打印

>>> f = open('dump.txt', 'wb')

# 創建文件對象

>>> pickle.dump(d, f) # d序列化,二進制格式寫入f

>>> f.close() # 關閉文件對象

2、反序列化

# pickle.loads()——根據生成的bytes 反序列化

x=b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.' #將序列化出的bytes 賦值給 x

>>> pickle.loads(x) # 反序列化

{'age': 20, 'score': 88, 'name': 'Bob'}

# pickle.load()——讀取file-like Object 的數據 反序列化

>>> f = open('dump.txt', 'rb') #創建可讀文件對象。格式為二進制

>>> d = pickle.load(f) # f 中讀取數據,反序列化

>>> f.close()

>>> d

{'age': 20, 'score': 88, 'name': 'Bob'}

3、註意

反序列化出的變量和原來的變量是完全不相幹的對象,它們只是內容相同而已

Pickle只能用於Python,並且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的數據

3JSON的序列化

如果要在不同的編程語言之間傳遞對象,就必須把對象序列化為標準格式。而JSON表示出來就是一個字符串,可以被所有語言讀取,也可以方便地存儲到磁盤或者通過網絡傳輸。

Python對象到JSON格式的轉換需要json模塊,它調用的方法同pickle模塊類似。

d = dict(name='Bob', age=20, score=88)

1、序列化

# json.dumps()——序列化並打印

>>> import json

>>> json.dumps(d)

'{"age": 20, "score": 88, "name": "Bob"}'

# json.dump——直接把JSON寫入一個file-like Object

2、反序列化

# json.loads()——把JSON的字符串反序列化

>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'

>>> json.loads(json_str)

{'age': 20, 'score': 88, 'name': 'Bob'}

# json.load()——從file-like Object中讀取字符串並反序列化

3class序列化為JSON

1、序列化

import json

class Student(object):

def __init__(self, name, age, score):

self.name = name

self.age = age

self.score = score

s = Student('Bob', 20, 88)

print(json.dumps(s))

如果我們直接將Student的實例序列化為JSON,則會報錯。這是因為默認情況下,dumps()方法不知道如何將Student的實例變為一個JSON的{}對象。

而可選參數default可以把任意一個對象變成一個 可序列為 JSON的對象,我們只需要為Student專門寫一個轉換函數,再把函數傳進去即可。

def student2dict(std):

return {

'name': std.name,

'age': std.age,

'score': std.score

}

Student實例首先被student2dict()函數轉換成一個可序列為JSONdict對象,然後再被順利序列化為JSON

>>> print(json.dumps(s, default=student2dict))

{"age": 20, "name": "Bob", "score": 88}

編寫專門的函數序列化,太過麻煩。更簡潔的方法如下:

# 把任意class的實例變為dict

# 將實例s,傳給 obj 參數,然後返回 obj.__dict__就是個dict

print(json.dumps(s, default=lambda obj: obj.__dict__))

通常class的實例都有一個__dict__屬性,它就是一個dict,用來存儲實例變量

>>> s.__dict__

{'name': 'Bob', 'age': 20, 'score': 88}

>>> type(s.__dict__)

<class 'dict'>

2、反序列化

loads()方法首先轉換出一個dict對象,然後,我們傳入的object_hook函數負責把dict轉換為Student實例

# dict 轉換為Student() 的函數

def dict2student(d):

return Student(d['name'], d['age'], d['score'])

>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}' # 需要反序列化的json字符串

>>> print(json.loads(json_str, object_hook=dict2student)) json_str通過dict2student 轉化為Student()

<__main__.Student object at 0x10cd3c190>


Python學習筆記__9.4章 序列化