开放的编程资料库

当前位置:我爱分享网 > Python教程 > 正文

Python使用pickle

Pythonpickle教程展示了如何使用pickle模块在Python中进行数据序列化。

泡菜模块

pickle模块实现了用于序列化和反序列化Python对象结构的二进制协议。序列化是将内存中的对象转换为可以存储在磁盘上或通过网络发送的字节流的过程。反序列化是将字节流转换为Python对象的过程。

此过程也称为pickling/unpickling或marshalling/unmarshalling。

pickletools模块包含用于分析pickle生成的数据流的工具。

Pythonpickle序列化

以下示例将数据序列化为二进制文件。

#!/usr/bin/python

import pickle

data = {
    'a': [1, 4.0, 3, 4+6j],
    'b': ("a red fox", b"and old falcon"),
    'c': {None, True, False}
}

with open('data.bin', 'wb') as f:
    pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)

我们有一个不同数据类型的字典。数据被pickle成一个二进制文件。

with open('data.bin', 'wb') as f:
    pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)

dump函数将对象的pickled表示写入文件对象。随着时间的推移,已经开发了几种协议。协议版本决定了序列化过程的能力。在我们的代码中,我们选择最高的协议版本。

$ hexdump -C data.bin
00000000  80 05 95 75 00 00 00 00  00 00 00 7d 94 28 8c 01  |...u.......}.(..|
00000010  61 94 5d 94 28 4b 01 47  40 10 00 00 00 00 00 00  |a.].(K.G@.......|
00000020  4b 03 8c 08 62 75 69 6c  74 69 6e 73 94 8c 07 63  |K...builtins...c|
00000030  6f 6d 70 6c 65 78 94 93  94 47 40 10 00 00 00 00  |omplex...G@.....|
00000040  00 00 47 40 18 00 00 00  00 00 00 86 94 52 94 65  |..G@.........R.e|
00000050  8c 01 62 94 8c 09 61 20  72 65 64 20 66 6f 78 94  |..b...a red fox.|
00000060  43 0e 61 6e 64 20 6f 6c  64 20 66 61 6c 63 6f 6e  |C.and old falcon|
00000070  94 86 94 8c 01 63 94 8f  94 28 89 88 4e 90 75 2e  |.....c...(..N.u.|
00000080

二进制文件不能用简单的文本编辑器读取;我们需要可以处理十六进制数据的工具。

Pythonpickle反序列化

在下一个示例中,我们从二进制文件中提取数据。

#!/usr/bin/python

import pickle

with open('data.bin', 'rb') as f:

    data = pickle.load(f)

    print(data)

load函数从文件对象中读取对象的pickled表示,并返回重构的对象。

$ ./simple_read.py
{'a': [1, 4.0, 3, (4+6j)], 'b': ('a red fox', b'and old falcon'),
    'c': {False, True, None}}

我们已经成功地重新创建了字典对象。

Pythonpickle转储/加载

dumps函数将对象的pickled表示作为字节对象返回,而不是将其写入文件。loads函数返回对象的腌制表示数据的重构对象层次结构。数据必须是类似字节的对象。

#!/usr/bin/python

import pickle


data = [1, 2, 3, 4, 5]

dumped = pickle.dumps(data)
print(dumped)

loaded = pickle.loads(dumped)
print(loaded)

在示例中,我们使用dumpsloads序列化和反序列化Python列表。

$ ./dumps_loads.py
b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x02K\x03K\x04K\x05e.'
[1, 2, 3, 4, 5]

Python泡菜__getstate__/__setstate__

pickling和unpickling的过程可以通过__getstate____setstate__函数来影响。__getstate__函数在pickling时调用,__setstate__函数在unpickling时调用。

blue, rock, water, sky, cloud, forest, hawk, falcon

这是words.txt文件

red, green, blue, pink, orange

这是colours.txt文件

#!/usr/bin/python

import pickle


class MyData:

    def __init__(self, filename):

        self.name = filename
        self.fh = open(filename)

    def __getstate__(self):

        odict = self.__dict__.copy()
        print(odict)
        del odict['fh']
        return odict

    def __setstate__(self, dict):

        fh = open(dict['name'])
        self.name = dict['name']
        self.fh = fh

obj = MyData('words.txt')

res = pickle.loads(pickle.dumps(obj))
print(res.fh.read())

obj2 = MyData('colours.txt')

res = pickle.loads(pickle.dumps(obj2))
print(res.fh.read())

在示例中,我们在__setstate____getstate__成员函数中存储和删除文件句柄。

$ ./state.py 
{'name': 'words.txt', 'fh': <_io.TextIOWrapper name='words.txt' mode='r' encoding='UTF-8'>}
blue, rock, water, sky, cloud, forest, hawk, falcon
{'name': 'colours.txt', 'fh': <_io.TextIOWrapper name='colours.txt' mode='r' encoding='UTF-8'>}
red, green, blue, pink, orange

Pythonpickle是不安全的

pickle模块是不安全的。该模块是一个虚拟机,它使用预定义的操作码来完成它的工作。通过使用特制的二进制字符串,攻击者可以启动系统命令来破坏数据或启动反向shell。

#!/usr/bin/python

import pickle

pickle.loads(b"cos\nsystem\n(S'ls -l'\ntR.")

此示例启动Linuxls命令。

$ ./insec.py 
total 36
drwxr-xr-x 2 user2 user2 4096 Aug 13 16:16 Desktop
drwxr-xr-x 2 user2 user2 4096 Aug 13 16:18 Documents
drwxr-xr-x 2 user2 user2 4096 Aug 13 16:16 Downloads
-rwxr-xr-x 1 user2 user2   79 Aug 29 11:08 insec.py
drwxr-xr-x 2 user2 user2 4096 Aug 13 16:16 Music
drwxr-xr-x 2 user2 user2 4096 Aug 13 16:16 Pictures
drwxr-xr-x 2 user2 user2 4096 Aug 13 16:16 Public
drwxr-xr-x 2 user2 user2 4096 Aug 13 16:16 Templates
drwxr-xr-x 2 user2 user2 4096 Aug 13 16:16 Videos

这是一个示例输出。

在本教程中,我们使用了Pythonpickle模块。

列出所有Python教程。

未经允许不得转载:我爱分享网 » Python使用pickle

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏