如何用Python保存数据?

16 投票
7 回答
19247 浏览
提问于 2025-04-15 14:08

我正在用Python写一个程序,想让用户能够保存他们正在处理的数据。我查了一下cPickle,感觉它是个快速又简单的保存数据的方法,但我觉得它不太安全。因为整个函数、类等等都可以被“腌制”(pickled),我担心如果有个坏的保存文件会把有害的代码注入到程序里。我想知道有没有办法防止这种情况,或者我应该考虑其他保存数据的方法,比如直接转换成字符串(这也感觉不太安全),或者创建一个XML结构,把数据放进去。

我对Python还很陌生,所以请多多包涵。

提前谢谢大家!

补充:我存储的数据主要是字典和列表,比如名字、速度等信息。目前这些数据比较简单,但将来可能会变得更复杂。

7 个回答

2

*****在这个回答中,我只关注应用程序完整性被意外破坏的情况。*****

Pickle是“安全的”。可能不安全的是访问你没有写的代码,比如在插件中;不过这和Pickle本身没有关系。

当你对一个对象进行Pickle操作时,所有的数据都会被保存,但代码和实现部分不会。这意味着当你反序列化(unpickle)这个对象时,可能会发现里面有“旧式”的数据(如果你更新了实现)。这点你必须了解并处理,视情况而定。

对字符串、列表、数字和字典进行Pickle操作非常简单,而且效果很好,和JSON差不多。Pickle的神奇之处在于——有时候甚至不需要调整——复杂的Python对象也能被Pickle。但要记住,只有数据被Pickle;对象的实例是通过保存的模块名和类型名简单重建的。

3

你可以这样做:

写入数据:

  • 使用Pickle
  • 给打包好的文件签名
  • 完成

读取数据:

  • 检查打包文件的签名
  • 解包
  • 使用数据

不过我想知道,你为什么觉得数据文件可能会被篡改,而你的应用程序却不会呢?

23

根据你的描述,使用JSON编码是一个安全又快速的解决方案。在Python 2.6中有一个json模块,你可以这样使用:

import json
obj = {'key1': 'value1', 'key2': [1, 2, 3, 4], 'key3': 1322}
encoded = json.dumps(obj)
obj = json.loads(encoded)

JSON格式是人类可读的,跟Python中的字典字符串表示方式很相似。而且它没有像pickle那样的安全问题。如果你没有Python 2.6,可以安装cjson或者simplejson

你不能用JSON来保存Python对象,就像用Pickle那样。但你可以用它来保存:字符串、字典、列表……这在大多数情况下已经足够了。

接下来解释一下为什么pickle不安全。根据Python的文档

大多数与pickle和cPickle模块相关的安全问题都涉及到反序列化(unpickling)。因为你(程序员)控制着pickle将要处理的对象,所以与序列化(pickling)相关的安全漏洞是没有的,序列化出来的只是一个字符串。

但是,对于反序列化,绝对不应该对来源不明的字符串进行反序列化,比如从网络套接字读取的字符串。这是因为反序列化可能会创建出意想不到的对象,甚至可能会运行这些对象的方法,比如它们的类构造函数或析构函数……这个故事的教训就是,你需要非常小心你应用程序反序列化的字符串的来源。

虽然有一些防范措施,但在你的情况下,使用JSON会简单得多。

撰写回答