长久保存python程序运行中得到的对象,类,函数,接口和线程等东西,方便以后使用,而不是简单的放入内存中关机断电就丢失数据。python模块大全中pickle可以将对象转换为一种可以传输或存储的格式,一般是字节流的格式,字节流格式可读性很差。
函数名 | 功能 |
---|---|
pickle.dump(对象,文件,[使用协议]) | 将要持久化的数据“对象”,保存到“文件”中,使用有3种协议,索引0为ASCII,1为旧式二进制,2为新式二进制协议 |
pickle.load(文件) | 从“文件”中读取字符串,将他们反序列化转换为python的数据对象,可以像操作数据类型的这些方法来操作它们。 |
pickle.loads(string) | 将obj对象序列化为string形式,而不是存入文件中。 |
pickle.loads(string) | 从string中读出序列化前的obj对象。 |
import _pickle as pickle
a = {" name ": "Tom", "age": "40"}
with open('text.txt', 'wb') as file:
pickle.dump(a, file)
with open('text.txt', 'rb') as file2:
b = pickle.load(file2)
f = open('text.txt', 'rb')
data = pickle.load(f)
print(type(data))
print(data)
得到的结果为
{'age': '40', ' name ': 'Tom'}
此时的text.txt中显示为序列化后的字节流
2. dumps和loads使用实例
import pprint
import _pickle as cpickle
import pickle
info=[1,2,3,'java','python']
print("原始数据:")
pprint.pprint(info)
data1=pickle.dumps(info)
data2=pickle.loads(data1)
print("序列化:",data1)
print("反序列化:",data2)
输出结果:
原始数据:
[1, 2, 3, 'java', 'python']
序列化: b'\x80\x03]q\x00(K\x01K\x02K\x03X\x04\x00\x00\x00javaq\x01X\x06\x00\x00\x00pythonq\x02e.'
反序列化: [1, 2, 3, 'java', 'python']
>>>stu = Student('Tom', 19, 1)
>>> print(stu)
Student [name: Tom, age: 19, sno: 1]
# 序列化
>>> var_b = pickle.dumps(stu)
>>> var_b
b'\x80\x03c__main__\nStudent\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Tomq\x04X\x03\x00\x00\x00ageq\x05K\x13X\x03\x00\x00\x00snoq\x06K\x01ub.'
# 反序列化
>>> var_c = pickle.loads(var_b)
>>> var_c
Student [name: Tom, age: 19, sno: 1]
# 持久化到文件
>>> with open('pickle.txt', 'wb') as f:
... pickle.dump(stu, f)
...
# 从文件总读取数据
>>> with open('pickle.txt', 'rb') as f:
... pickle.load(f)
...
Student [name: Tom, age: 19, sno: 1]
# countdown.py
import time
import threading
class Countdown:
def __init__(self, n):
self.n = n
self.thr = threading.Thread(target=self.run)
self.thr.daemon = True
self.thr.start()
def run(self):
while self.n > 0:
print('T-minus', self.n)
self.n -= 1
time.sleep(5)
def __getstate__(self):
return self.n
def __setstate__(self, n):
self.__init__(n)
试着运行下面的序列化试验代码:
>>> f = open('cstate.p', 'rb')
>>> pickle.load(f)
countdown.Countdown object at 0x10069e2d0>
T-minus 19
T-minus 18
...
你可以看到线程又奇迹般的重生了,从你第一次序列化它的地方又恢复过来。
pickle 对于大型的数据结构比如使用 array 或 numpy 模块创建的二进制数组效率并不是一个高效的编码方式。 如果你需要移动大量的数组数据,你最好是先在一个文件中将其保存为数组数据块或使用更高级的标准编码方式如HDF5 (需要第三方库的支持)。
由于 pickle 是Python特有的并且附着在源码上,所有如果需要长期存储数据的时候不应该选用它。 例如,如果源码变动了,你所有的存储数据可能会被破坏并且变得不可读取。 坦白来讲,对于在数据库和存档文件中存储数据时,你最好使用更加标准的数据编码格式如XML,CSV或JSON。 这些编码格式更标准,可以被不同的语言支持,并且也能很好的适应源码变更。
最后一点要注意的是 pickle 有大量的配置选项和一些棘手的问题。 对于最常见的使用场景,你不需要去担心这个,但是如果你要在一个重要的程序中使用pickle去做序列化的话, 最好去查阅一下 官方文档 。