【问题标题】:Easiest way to persist a data structure to a file in python?将数据结构持久保存到python中的文件的最简单方法?
【发布时间】:2009-06-26 04:22:39
【问题描述】:

假设我有这样的事情:

d = { "abc" : [1, 2, 3], "qwerty" : [4,5,6] }

以编程方式将其放入我以后可以从 python 加载的文件中的最简单方法是什么?

我能否以某种方式将其保存为 python 源代码(从 python 脚本中,而不是手动!),然后import 稍后再保存?

或者我应该使用 JSON 还是什么?

【问题讨论】:

  • 还有更多:datasetjsonpickle
  • 最简单的方法是 JSON,因为它的结构化数据类似于 Python 字典。幸运的是,python 有一个捆绑的 JSON 模块。您只需import json

标签: python file persistence


【解决方案1】:

使用pickle 模块。

import pickle
d = { "abc" : [1, 2, 3], "qwerty" : [4,5,6] }
afile = open(r'C:\d.pkl', 'wb')
pickle.dump(d, afile)
afile.close()

#reload object from file
file2 = open(r'C:\d.pkl', 'rb')
new_d = pickle.load(file2)
file2.close()

#print dictionary object loaded from file
print new_d

【讨论】:

  • 路径前面的r是什么意思?
  • r'' 表示原始字符串,如下所述:docs.python.org/reference/lexical_analysis.html#string-literals。基本上,这意味着字符串中的反斜杠包含为文字反斜杠,而不是字符转义(尽管原始字符串不能以反斜杠结尾)。
  • 我已经更正了这个例子——文件需要以二进制模式打开。它仍然需要用于 Python 2,但不会失败。
  • 确保您阅读了 Python 文档(包括相应版本的文档)并且不要仅仅依赖示例! :) docs.python.org/3.0/library/pickle.html(对不起,垃圾评论!)
  • 技术上酸洗将适用于文本模式文件,只要您不使用二进制泡菜格式(即协议 = 0)并且始终使用它(即也使用文本模式进行阅读)背部)。不过,使用二进制通常是一个更好的主意,尤其是当您可以在平台之间移动数据时。
【解决方案2】:

任您选择:Python Standard Library - Data Persistance。哪一个最合适可能会因您的具体需求而异。

pickle 就“将任意对象写入文件并恢复它”而言可能是最简单和最强大的——它可以自动处理自定义类和循环引用。

为了获得最佳酸洗性能(速度和空间),请使用cPickle HIGHEST_PROTOCOL

【讨论】:

    【解决方案3】:

    试试 shelve 模块,它会给你持久的字典,例如:

    import shelve
    d = { "abc" : [1, 2, 3], "qwerty" : [4,5,6] }
    
    shelf = shelve.open('shelf_file')
    for key in d:
        shelf[key] = d[key]
    
    shelf.close()
    
    ....
    
    # reopen the shelf
    shelf = shelve.open('shelf_file')
    print(shelf) # => {'qwerty': [4, 5, 6], 'abc': [1, 2, 3]}
    

    【讨论】:

      【解决方案4】:

      JSON有毛病,但当它满足你的需求时,也是:

      • 使用简单
      • 作为json module 包含在标准库中
      • 接口有点类似于pickle,可以处理更复杂的情况
      • 用于调试、共享和版本控制的人工可编辑文本
      • 有效的 Python 代码
      • 在网络上已广为人知(如果您的程序涉及该领域的任何一个)

      【讨论】:

      • JSON 不是有效的 Python。表面上看起来是这样,但是使用一些布尔值,你会发现问题(JSON 使用 true 和 false,而 Python 使用 True 和 False)。另外:JSON 数组(dicts)只有字符串键。所以它不能正确地保存数据结构。
      【解决方案5】:

      您可能还想看看Zope's Object Database,您越复杂:-) 对您所拥有的东西来说可能有点矫枉过正,但它可以很好地扩展并且使用起来并不难。

      【讨论】:

        【解决方案6】:

        只是补充前面的建议,如果您希望文件格式易于阅读和修改,您也可以使用YAML。它非常适用于嵌套的字典和列表,但也适用于更复杂的数据结构(即涉及自定义对象的数据结构),其最大的优点是格式可读。

        【讨论】:

          【解决方案7】:

          如果您想以易于阅读的类似 JSON 的格式保存它,请使用 repr 序列化对象并使用 eval 反序列化它。

          repr(object) -> string

          返回对象的规范字符串表示。 对于大多数对象类型,eval(repr(object)) == object

          【讨论】:

          • 考虑 ast.literal_eval() (docs.python.org/library/ast.html#ast.literal_eval) 作为 eval() 的替代方案。
          • 我不喜欢这个解决方案的主要原因是你在结构中有一个对象 eval(repr()) 身份不成立,repr() 将“成功”但是然后 eval() 会呕吐。
          • @John 你会因为那个答案而被嘲笑……是 S.Lott 的吗?
          • pickle、YAML、JSON 等都比这种方法更安全,并且可以使用更多类型。 IMO,应尽可能避免使用 eval()。
          • @Jason:实际上,pickle 并不比 eval 更安全 - 恶意输入可以同样轻松地执行代码,至少在这里很明显它正在这样做,所以我认为这是一个有点不公平。还有其他避免 eval() 的原因(例如,仅处理具有可评估 repr() 的对象,如果它们不进行自我评估,则会默默地丢失数据,正如 Miles 指出的那样),但在安全方面,它并不比 pickle 差。
          猜你喜欢
          • 2015-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-15
          • 2015-06-23
          • 2010-11-20
          • 1970-01-01
          • 2021-11-20
          相关资源
          最近更新 更多