• python3_pickle模块详解


    python3 pickle持久化的储存数据。

    python程序运行中得到了一些字符串,列表,字典等数据,想要长久的保存下来,方便以后使用,而不是简单的放入内存中关机断电就丢失数据。python模块大全中pickle模块就排上用场了, 他可以将对象转换为一种可以传输或存储的格式。

    pickle对象串行化

    • pickle模块将任意一个python对象转换成一系统字节的这个操作过程叫做串行化对象;

    pickle与cpickle比较

    • pickle完全用python来实现的,cpickle用C来实现的,cpickle的速度要比pickle快好多倍,电脑中如果有cpickle的话建议使用cpickle。

    pickle模块中常用的函数:

    1. pickle.dump(obj, file, [,protocol])
      • 含义:pickle.dump(对象,文件,[使用协议])
      • 将要持久化的数据“对象”,保存到“文件”中,使用有3种协议,索引0为ASCII,1为旧式二进制,2为新式二进制协议,不同之处在于2要更高效一些。
      • 默认dump方法使用0做协议
    2. pickle.load(file)
      • 含义:pickle.load(文件),将file中的对象序列化读出。
      • 从“文件”中读取字符串,将他们反序列化转换为python的数据对象,可以像操作数据类型的这些方法来操作它们;  
    3. pickle.dumps(obj[, protocol])
      • 函数的功能:将obj对象序列化为string形式,而不是存入文件中。
      • obj:想要序列化的obj对象。
      • protocal:如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。
    4. pickle.loads(string)
      • 函数的功能:从string中读出序列化前的obj对象。
      • string:文件名称。

    dump() 与 load() 相比 dumps() 和 loads() 还有另一种能力:dump()函数能一个接一个地将几个对象序列化存储到同一个文件中,随后调用load()来以同样的顺序反序列化读出这些对象。

    pickle实例代码:

    1、一个字典a,用dumple()存储到本地文件,所存数据的格式就是字典,而普通的file.write()写入文件的是字符串。读取时,load()返回的是一个字典,file.read()返回的是一个字符串。

     1 import pickle
     2 
     3 
     4 a = {" name ": "Tom", "age": "40"}
     5 with open('text.txt', 'wb') as file:
     6     pickle.dump(a, file)
     7 
     8 with open('text.txt', 'rb') as file2:
     9     b = pickle.load(file2)
    10 
    11 print(type(b))
    12 print(b)

    执行结果:

    /usr/bin/python3.5 /home/rxf/python3_1000/1000/python3_server/python_pickle/example.py
    <class 'dict'>
    {'age': '40', ' name ': 'Tom'}

    2、一个列表info,用 pickle.dumps()方法将info序列化为string形式,而不是存入文件中。用pickle.loads()方法从string(文件名称data1)读出序列化前的对象。

     1 import pickle
     2 import pprint
     3 
     4 info = [1, 2, 3, 'abc', 'ilovepython']
     5 print('原始数据:')
     6 pprint.pprint(info)
     7 
     8 data1 = pickle.dumps(info)
     9 data2 = pickle.loads(data1)
    10 
    11 print("序列化:%r" % data1)
    12 print("反序列化: %r" % data2)

    执行结果:

    /usr/bin/python3.5 /home/rxf/python3_1000/1000/python3_server/python_pickle/demo1.py
    原始数据:
    [1, 2, 3, 'abc', 'ilovepython']
    序列化:b'x80x03]qx00(Kx01Kx02Kx03Xx03x00x00x00abcqx01Xx0bx00x00x00ilovepythonqx02e.'
    反序列化: [1, 2, 3, 'abc', 'ilovepython']
    
    Process finished with exit code 0

    3、pickle模块主要函数实例

     1 # pickle模块主要函数的应用举例
     2 import pickle
     3 import pprint
     4 
     5 dataList = [[8, 1, 'python'],
     6             [8, 1, 'python'],
     7             [8, 0, 'python'],
     8             [8, 1, 'C++'],
     9             [8, 1, 'C++']]
    10 dataDic = {0: [1, 2, 3, 4],
    11            1: ('a', 'b'),
    12            2: {'c': 'yes', 'd': 'no'}}
    13 print("原始数据dataList:")
    14 pprint.pprint(dataList)
    15 print('
    ')
    16 print("原始数据dataDic:")
    17 pprint.pprint(dataDic)
    18 
    19 # 使用dump()将数据序列化到文件中
    20 fw = open('dataFile.txt', 'wb')
    21 # Pickle the list using the highest protocol available.
    22 pickle.dump(dataList, fw)
    23 # Pickle dictionary using protocol 0.
    24 pickle.dump(dataDic, fw)
    25 fw.close()
    26 
    27 # 使用load()将数据从文件中序列化读出
    28 fr = open('dataFile.txt', 'rb')
    29 data1 = pickle.load(fr)
    30 print('
    '+"反序列化1:%r" % data1)
    31 data2 = pickle.load(fr)
    32 print("反序列化2:%r" % data2 + '
    ')
    33 fr.close()
    34 
    35 # 使用dumps()和loads()举例
    36 p = pickle.dumps(dataList)
    37 print(pickle.loads(p))
    38 p = pickle.dumps(dataDic)
    39 print(pickle.loads(p))

    执行结果:

    /usr/bin/python3.5 /home/rxf/python3_1000/1000/python3_server/python_pickle/demo2.py
    原始数据dataList:
    [[8, 1, 'python'],
     [8, 1, 'python'],
     [8, 0, 'python'],
     [8, 1, 'C++'],
     [8, 1, 'C++']]
    
    
    原始数据dataDic:
    {0: [1, 2, 3, 4], 1: ('a', 'b'), 2: {'c': 'yes', 'd': 'no'}}
    
    反序列化1:[[8, 1, 'python'], [8, 1, 'python'], [8, 0, 'python'], [8, 1, 'C++'], [8, 1, 'C++']]
    反序列化2:{0: [1, 2, 3, 4], 1: ('a', 'b'), 2: {'d': 'no', 'c': 'yes'}}
    
    [[8, 1, 'python'], [8, 1, 'python'], [8, 0, 'python'], [8, 1, 'C++'], [8, 1, 'C++']]
    {0: [1, 2, 3, 4], 1: ('a', 'b'), 2: {'d': 'no', 'c': 'yes'}}
    
    Process finished with exit code 0

    4、要注意的是,在load(file)时,要让python能够找到类的定义,否则会报错:

     1 import pickle
     2 
     3 
     4 class Person:
     5     def __init__(self, name, age):
     6         self.name = name
     7         self.age = age
     8 
     9     def show(self):
    10         print(self.name+"_"+str(self.age))
    11 
    12 aa = Person("Battier", 6)
    13 aa.show()
    14 
    15 f = open('./demo3.txt', 'wb')
    16 pickle.dump(aa, f, 0)
    17 f.close()
    18 
    19 # del Person
    20 f = open('./demo3.txt', 'rb')
    21 bb = pickle.load(f)
    22 
    23 f.close()
    24 bb.show()

    如果不注释掉del Person的话,那么会报错:(意思就是当前的模块找不到类了)

    /usr/bin/python3.5 /home/rxf/python3_1000/1000/python3_server/python_pickle/demo3.py
    Battier_6
    Traceback (most recent call last):
      File "/home/rxf/python3_1000/1000/python3_server/python_pickle/demo3.py", line 21, in <module>
        bb = pickle.load(f)
    AttributeError: Can't get attribute 'Person' on <module '__main__' from '/home/rxf/python3_1000/1000/python3_server/python_pickle/demo3.py'>
    
    Process finished with exit code 1

    5、清空pickler的“备忘”,使用Pickler实例在序列化对象的时候,它会“记住”已经被序列化的对象引用,所以对同一对象多次调用dump(obj),pickler不会“傻呼呼”的去多次序列化。

     1 import pickle
     2 import io
     3 
     4 
     5 class Person:
     6     def __init__(self, name, age):
     7         self.name = name
     8         self.age = age
     9 
    10     def show(self):
    11         print(self.name + "_"+str(self.age))
    12 
    13 aa = Person("Battier", 6)
    14 aa.show()
    15 
    16 
    17 fle = io.BytesIO()
    18 pick = pickle.Pickler(fle)
    19 pick.dump(aa)
    20 val1 = fle.getvalue()
    21 print(len(val1))
    22 
    23 pick.clear_memo()
    24 pick.dump(aa)
    25 val2 = fle.getvalue()
    26 print(len(val2))
    27 fle.close()

    上面代码运行结果:

    /usr/bin/python3.5 /home/rxf/python3_1000/1000/python3_server/python_pickle/demo4.py
    Battier_6
    69
    138
    
    Process finished with exit code 0

    再注释掉pick.clear_memo()后,运行结果如下:

    /usr/bin/python3.5 /home/rxf/python3_1000/1000/python3_server/python_pickle/demo4.py
    Battier_6
    69
    74
    
    Process finished with exit code 0

    主要是因为,python的pickle如果不clear_memo,则不会多次去序列化对象。

  • 相关阅读:
    计算与软件工程 作业一
    C语言程序设计数组实验实验报告
    C语言程序设计第五次实验报告
    C语言程序设计第四次实验报告
    C语言程序设计第三次实验报告
    C程序设计实验报告第二次实验
    关于证书如何完成身份验证(SSL证书)
    openflow流表项中有关ip掩码的匹配的问题(控制器为ryu)
    解决sublime安装插件被墙失败的方法
    区块链技术与应用(二)之比特币中的数据结构
  • 原文地址:https://www.cnblogs.com/ranxf/p/7800179.html
Copyright © 2020-2023  润新知