【Python 第65课】pickle

在之前的课程中,我们有讲到通过文件来保存、中转数据(参见第31、32、33课)。在使用文件存储时,通常需要对数据进行一些处理,按照一定的规范把数据整理成文本,再写入文件中。下次使用时,从文件中读出文本,再按照此规范解析这些数据。

这种将数据转成文本的过程又被称为“序列化”,即将对象状态转换为可保持或传输的格式的过程。对应的,从序列化的格式中解析对象状态的过程被称为“反序列化”。

在之前的课程和示例中,我们都自己手动实现了这个过程。其实 Python 提供了一个标准模块来做这件事,就是 pickle。它可以把任何 Python 对象存储在文件中,再把它原样取出来。

来看一下存储的过程:

import pickle

test_data = ['Save me!', 123.456, True]

f = file('test.data', 'w')

pickle.dump(test_data, f)

f.close()

这样,我们就把 test_data 这个 list 存储在了文件 test.data 中。你可以用文本编辑器打开 test.data 查看里面的内容:

(lp0

S'Save me!'

p1

aF123.456

aI01

a.

这就是经 pickle 序列化后的数据,隐约可以看到之前对象的影子。你可能无法看出这个文件的规律,这没关系,Python 能看懂就可以了。

下面取存储的过程:

import pickle

f = file('test.data')

test_data = pickle.load(f)

f.close()

print test_data

控制台的输出:

['Save me!', 123.456, True]

和存储前的数据是一致的。

如果你想保存多个对象,一种方法是把这些对象先全部放在一个序列中,在对这个序列进行存储:

a = 123

b = "hello"

c = 0.618

data = (a, b, c)

...

pickle.dump(data, f)

另一种方法就是依次保存和提取:

...

pickle.dump(a, f)

pickle.dump(b, f)

pickle.dump(c, f)

...

x = pickle.load(f)

y = pickle.load(f)

z = pickle.load(f)

dump 方法可以增加一个可选的参数,来指定用二进制来存储:

pickle.dump(data, f, True)

而 load 方法会自动检测数据是二进制还是文本格式,无需手动指定。

Python 还提供了另一个模块 cPickle,它的功能及用法和 pickle 模块完全相同,只不过它是用C语言编写的,因此要快得多(比pickle快1000倍)。因此你可以把上述代码中的 pickle 全部替换为 cPickle,从而提高运行速度(尽管在这个小程序中影响微乎其微)。

原文发布于微信公众号 - Crossin的编程教室(crossincode)

原文发表时间:2014-04-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Vamei实验室

Linux并发与同步

典型的UNIX系统都支持一个进程创建多个线程(thread)。在Linux进程基础中提到,Linux以进程为单位组织操作,Linux中的线程也都基于进程。尽管实...

2739
来自专栏后端技术探索

利用 PHP 名称空间编写可读且可维护的代码

“Conan 是我榜样。” 如果我在餐桌上说这句话,我儿子会以为我说的是游戏 “野蛮人柯南”,而我妻子会以为我说的是脱口秀主持人 Conan O'Brien。这...

1332
来自专栏从零开始的linux

grep

grep文本过滤 命令选项: -v: 反向选取 -o: 仅显示匹配的字串,而非字串所在的行 ...

3134
来自专栏月牙寂

k8s源码分析------kube-apiserver分析(1)

第一时间获取文章,可以关注本人公众号 月牙寂道长 yueyajidaozhang

5486
来自专栏Java技术分享

Redis特性和应用场景

Redis特性 速度快 Redis使用标准C编写实现,而且将所有数据加载到内存中,所以速度非常快。官方提供的数据表明,在一个普通的Linux机器上,Redis读...

1.1K7
来自专栏java工会

Java 动态代理及 RPC 框架介绍

所谓动态代理,指的是语言提供的一种语法,能够将对对象中不同方法的调用重定向到一个统一的处理函数中来。 python重写__getattr__函数能够做到这一点,...

1191
来自专栏架构说

c++在编译中遇到符合不存在如何解决?

今日问题:symbol 不存在 : symbol lookup error: ./libinterface.so: undefined symbol: _ZN...

35115
来自专栏CSDN技术头条

史上最难的一道Java面试题:分析篇

无意中了解到如下题目,觉得蛮好。 题目如下: ? 该程序的输出结果? 在java中,多线程的程序最难理解、调试,很多时候执行结果并不像我们想象的那样执行。所以在...

2257
来自专栏码云1024

net框架运行原理

2853
来自专栏Java技术分享

Redis特性和应用场景

Redis使用标准C编写实现,而且将所有数据加载到内存中,所以速度非常快。官方提供的数据表明,在一个普通的Linux机器上,Redis读写速度分别达到81000...

2867

扫码关注云+社区

领取腾讯云代金券