【问题标题】:With Python, can I keep a persistent dictionary and modify it?使用 Python,我可以保留一个持久字典并对其进行修改吗?
【发布时间】:2009-08-04 18:10:52
【问题描述】:

所以,我想将字典存储在持久文件中。有没有办法使用常规字典方法从该文件中的字典中添加、打印或删除条目?

看来我可以使用 cPickle 来存储字典并加载它,但我不知道从那里获取它。

【问题讨论】:

  • 当你阅读pickle文档时,你有什么问题?您可以发布一些代码来展示您的工作以及您需要帮助的内容吗?
  • 基本上,我想将字典用作数据库类型的东西。因此,我可以将字典写入文件,然后在我想向字典中添加内容时将文件加载到我的脚本中,但使用常规字典方法。有没有办法我可以加载文件,然后用典型的 dict["key"] = "items" 或 del dict["key"] 修改字典?我现在尝试这样做,python 告诉我 dict 在这个特定示例中是未定义的。

标签: python dictionary persistence object-persistence


【解决方案1】:

如果您的键(不一定是值)是字符串,shelve 标准库模块可以无缝地执行您想要的操作。

【讨论】:

  • Il piacere é tutto mio, Stefano!-)
  • 值得注意的是,这不适用于对字典中包含的元素进行的编辑。因此,如果您有一个名为 data 的搁板,其中包含项目列表,那么 data['items'].append(123) 将失败。
【解决方案2】:

使用 JSON

与 Pete 的回答类似,我喜欢使用 JSON,因为它可以很好地映射到 python 数据结构并且非常易读:

持久化数据是微不足道的:

>>> import json
>>> db = {'hello': 123, 'foo': [1,2,3,4,5,6], 'bar': {'a': 0, 'b':9}}
>>> fh = open("db.json", 'w')
>>> json.dump(db, fh)

加载也差不多:

>>> import json
>>> fh = open("db.json", 'r')
>>> db = json.load(fh)
>>> db
{'hello': 123, 'bar': {'a': 0, 'b': 9}, 'foo': [1, 2, 3, 4, 5, 6]}
>>> del new_db['foo'][3]
>>> new_db['foo']
[1, 2, 3, 5, 6]

此外,JSON 加载不会像 shelvepickle 那样遇到同样的安全问题,尽管 IIRC 比 pickle 慢。

如果你想在每个操作上写:

如果你想保存每个操作,你可以继承 Python dict 对象:

import os
import json

class DictPersistJSON(dict):
    def __init__(self, filename, *args, **kwargs):
        self.filename = filename
        self._load();
        self.update(*args, **kwargs)

    def _load(self):
        if os.path.isfile(self.filename) 
           and os.path.getsize(self.filename) > 0:
            with open(self.filename, 'r') as fh:
                self.update(json.load(fh))

    def _dump(self):
        with open(self.filename, 'w') as fh:
            json.dump(self, fh)

    def __getitem__(self, key):
        return dict.__getitem__(self, key)

    def __setitem__(self, key, val):
        dict.__setitem__(self, key, val)
        self._dump()

    def __repr__(self):
        dictrepr = dict.__repr__(self)
        return '%s(%s)' % (type(self).__name__, dictrepr)

    def update(self, *args, **kwargs):
        for k, v in dict(*args, **kwargs).items():
            self[k] = v
        self._dump()

你可以这样使用:

db = DictPersistJSON("db.json")
db["foo"] = "bar" # Will trigger a write

效率极低,但可以让你快速起步。

【讨论】:

【解决方案3】:

程序加载时从文件中解压,在程序运行时修改为内存中的普通字典,程序退出时腌到文件?不确定您在这里还要求什么。

【讨论】:

    【解决方案4】:

    假设键和值具有 repr 的有效实现,一种解决方案是将字典 (repr(dict)) 的字符串表示形式保存到文件中。您可以使用 eval 函数 (eval(inputstring)) 加载它。这种技术有两个主要缺点:

    1) Is 不适用于具有无法使用的 repr 实现的类型(或者甚至可能看起来有效,但失败了)。您至少需要注意正在发生的事情。

    2) 您的文件加载机制基本上是直接执行 Python 代码。除非您完全控制输入,否则对安全性不利。

    它有一个优点:非常容易做到。

    【讨论】:

    • ast.literal_eval() 如果你的 dict 只包含基本的 Python 类型。
    【解决方案5】:

    我最喜欢的方法(不使用标准 python 字典函数):使用PyYaml 读/写 YAML 文件。 See this answer for details,总结在这里:

    创建一个 YAML 文件,“employment.yml”:

    new jersey:
      mercer county:
        pumbers: 3
        programmers: 81
      middlesex county:
        salesmen: 62
        programmers: 81
    new york:
      queens county:
        plumbers: 9
        salesmen: 36
    

    第 3 步:用 Python 阅读

    import yaml
    file_handle = open("employment.yml")
    my__dictionary = yaml.safe_load(file_handle)
    file_handle.close()
    

    现在 my__dictionary 具有所有值。如果您需要即时执行此操作,请创建一个包含 YAML 的字符串并使用 yaml.safe_load 对其进行解析。

    【讨论】:

      【解决方案6】:

      如果仅使用字符串作为键(shelve 模块允许)是不够的,FileDict 可能是解决此问题的好方法。

      【讨论】:

        【解决方案7】:

        酸洗有一个缺点。如果您的字典必须经常从磁盘读取和写入并且它很大,那么它可能会很昂贵。泡菜把东西倒掉(整个)。 unpickle 把东西弄起来(作为一个整体)。

        如果你必须处理小字典,pickle 是可以的。如果您要处理更复杂的事情,请选择 berkelydb。它基本上是用来存储键值对的。

        【讨论】:

          【解决方案8】:

          您考虑过使用 dbm 吗?

          import dbm
          import pandas as pd
          import numpy as np
          db = b=dbm.open('mydbm.db','n')
          
          #create some data
          df1 = pd.DataFrame(np.random.randint(0, 100, size=(15, 4)), columns=list('ABCD'))
          df2 = pd.DataFrame(np.random.randint(101,200, size=(10, 3)), columns=list('EFG'))
          
          #serialize the data and put in the the db dictionary
          db['df1']=df1.to_json()
          db['df2']=df2.to_json()
          
          
          # in some other process:
          db=dbm.open('mydbm.db','r')
          df1a = pd.read_json(db['df1'])
          df2a = pd.read_json(db['df2'])
          

          即使没有 db.close() 也能正常工作

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-06-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-22
          • 2022-12-03
          • 1970-01-01
          • 1970-01-01
          • 2011-12-22
          相关资源
          最近更新 更多