14

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

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

4

8 回答 8

18

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

于 2009-08-04T18:17:27.153 回答
10

使用 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

这是非常低效的,但可以让你快速起步。

于 2014-04-17T15:38:26.723 回答
6

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

于 2009-08-04T18:13:07.193 回答
1

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

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

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

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

于 2009-08-04T18:24:22.460 回答
1

我最喜欢的方法(不使用标准 python 字典函数):使用PyYaml读/写 YAML 文件。 有关详细信息,请参阅此答案,此处总结:

创建一个 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 对其进行解析。

于 2009-08-04T19:09:22.230 回答
1

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

于 2012-08-21T16:02:21.880 回答
0

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

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

于 2009-08-04T19:03:14.143 回答
0

您是否考虑过使用 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() 这往往也能工作

于 2020-12-30T19:26:01.407 回答