如何用Python保存数据?
我正在用Python写一个程序,想让用户能够保存他们正在处理的数据。我查了一下cPickle,感觉它是个快速又简单的保存数据的方法,但我觉得它不太安全。因为整个函数、类等等都可以被“腌制”(pickled),我担心如果有个坏的保存文件会把有害的代码注入到程序里。我想知道有没有办法防止这种情况,或者我应该考虑其他保存数据的方法,比如直接转换成字符串(这也感觉不太安全),或者创建一个XML结构,把数据放进去。
我对Python还很陌生,所以请多多包涵。
提前谢谢大家!
补充:我存储的数据主要是字典和列表,比如名字、速度等信息。目前这些数据比较简单,但将来可能会变得更复杂。
7 个回答
*****在这个回答中,我只关注应用程序完整性被意外破坏的情况。*****
Pickle是“安全的”。可能不安全的是访问你没有写的代码,比如在插件中;不过这和Pickle本身没有关系。
当你对一个对象进行Pickle操作时,所有的数据都会被保存,但代码和实现部分不会。这意味着当你反序列化(unpickle)这个对象时,可能会发现里面有“旧式”的数据(如果你更新了实现)。这点你必须了解并处理,视情况而定。
对字符串、列表、数字和字典进行Pickle操作非常简单,而且效果很好,和JSON差不多。Pickle的神奇之处在于——有时候甚至不需要调整——复杂的Python对象也能被Pickle。但要记住,只有数据被Pickle;对象的实例是通过保存的模块名和类型名简单重建的。
你可以这样做:
写入数据:
- 使用Pickle
- 给打包好的文件签名
- 完成
读取数据:
- 检查打包文件的签名
- 解包
- 使用数据
不过我想知道,你为什么觉得数据文件可能会被篡改,而你的应用程序却不会呢?
根据你的描述,使用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会简单得多。