Python3:_pickle使用方法

_pickle的使用方法

  • _pickle作用
  • python3的_pickle和python2的cpickle的区别
  • pickle模块中常用的函数:
  • 参考网站

_pickle作用

长久保存python程序运行中得到的对象,类,函数,接口和线程等东西,方便以后使用,而不是简单的放入内存中关机断电就丢失数据。python模块大全中pickle可以将对象转换为一种可以传输或存储的格式,一般是字节流的格式,字节流格式可读性很差。

python3的_pickle和python2的cpickle的区别

  1. python3 中将python2的cpickle更名为_pickle,python3中既有pickle,也有_pickle,pickle模块由python编写,_pickle由C编写。;
  2. _pickle由于是由C编写,因此运行速度很快

pickle模块中常用的函数:

函数名 功能
pickle.dump(对象,文件,[使用协议]) 将要持久化的数据“对象”,保存到“文件”中,使用有3种协议,索引0为ASCII,1为旧式二进制,2为新式二进制协议
pickle.load(文件) 从“文件”中读取字符串,将他们反序列化转换为python的数据对象,可以像操作数据类型的这些方法来操作它们。
pickle.loads(string) 将obj对象序列化为string形式,而不是存入文件中。
pickle.loads(string) 从string中读出序列化前的obj对象。
  1. dump和load使用实例
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']
  1. dump&load和dumps&loads的区别:
    dump() 与 load() 相比 dumps() 和 loads() 还有另一种能力:dump()函数能一个接一个地将几个对象序列化存储到同一个文件中,随后调用load()来以同样的顺序反序列化读出这些对象。
  2. 对于类的序列化
>>>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]
  1. 有些类型的对象是不能被序列化的。这些通常是那些依赖外部系统状态的对象, 比如打开的文件,网络连接,线程,进程,栈帧等等。 用户自定义类可以通过提供 getstate() 和 setstate() 方法来绕过这些限制。 如果定义了这两个方法,pickle.dump() 就会调用 getstate() 获取序列化的对象。 类似的,setstate() 在反序列化时被调用。为了演示这个工作原理, 下面是一个在内部定义了一个线程但仍然可以序列化和反序列化的类:
# 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去做序列化的话, 最好去查阅一下 官方文档 。

参考网站

  1. https://python3-cookbook.readthedocs.io/zh_CN/latest/c05/p21_serializing_python_objects.html
  2. https://www.cnblogs.com/yyds/p/6563608.html

你可能感兴趣的:(Python3:_pickle使用方法)