Python pickle模块的使用方法

Python内置的pickle模块可以完成python对象的序列化,实现永久储存。使用起来非常之方便。

以下是使用的例子:

>>> a_list = [1,2,3,4,5,6]
>>> a_set = {'one', 'two', 'three'}
>>> a_dict = {1:'one', 2:'two', 3:'three'}
>>> a_tuple = ('a', 'b', 'c')
>>> a_mix = {1:['one', {1.0, 1}], 2:['two', {1.0, 1}]}
>>> import pickle
>>> with open('everything.pickle', 'wb') as f:
        # 使用pickle.dump方法将对象按照pickle协议序列化,并存到文件everything.pickle中
        pickle.dump(a_list, f)  
        pickle.dump(a_set, f)
        pickle.dump(a_dict, f)
        pickle.dump(a_tuple, f)
        pickle.dump(a_mix, f)

  
>>> with open('everything.pickle', 'rb') as f:
        # 使用pickle.load方法,将对象从文件中读取出来
        b_list = pickle.load(f)
        b_set = pickle.load(f)
        b_dict = pickle.load(f)
        b_tuple = pickle.load(f)
        b_mix = pickle.load(f)

  
>>> # 检测读取的对象跟原对象是否相同
>>> a_list == b_list and a_set == b_set and a_dict == b_dict and a_tuple == b_tuple and a_mix == b_mix
True

pickle模块中有dump方法和dumps方法,用于对象序列化,他们的区别是,dump方法将序列化的对象存入文件中,而dumps方法将序列化的对象返回成bytes对象。

与之相对应的有load方法和loads方法,用于对象反序列化,区别是load是从文件中读取,而loads是从bytes对象中读取。

>>> a_list
[1, 2, 3, 4, 5, 6]
>>> a_list_bytes = pickle.dumps(a_list) # 将a_list序列化成bytes对象,并储存在a_list_bytes中
>>> a_list_bytes # 序列化后的a_list对象
b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04K\x05K\x06e.'
>>> b_list = pickle.loads(a_list_bytes) # 将a_list_bytes反序列化,并赋值给b_list
>>> b_list # b_list和a_list完全一样
[1, 2, 3, 4, 5, 6]

 

pickle模块可以序列化用户自定义类:

>>> class Person:
        def __init__(self, name):
            self.name = name
        def say(self):
            print(self.name)
  
>>> a_person = Person('tim')
>>> data = pickle.dumps(a_person)
>>> data
b'\x80\x03c__main__\nPerson\nq\x00)\x81q\x01}q\x02X\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00timq\x04sb.'
>>> new_person = pickle.loads(data)
>>> new_person.say()
tim

可以看到被序列化内容中有__main__和Person的字眼,也就是__name__和类名,可以看出pickle是通过__name__和类名来识别对象的,所以当跨程序复用pickle序列化的用户自定义类的时候,一定要有相应的类的声明。

 

注意事项:

  • pickle使用二进制形式来序列化,所以写入或读取文件时要用二进制模式
  • pickle是专门针对python设计的,不支持跨语言使用
  • 因为是二进制形式,序列化的内容不具有可读性
  • pickle协议有很多个版本,新版本会兼容老版本,但老版本不支持新版本,因为老版本没有新版本的数据结构。关于pickle协议版本的信息参见这个连接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据