使用Python,我可以保留一个持久性字典并修改它吗?

使用Python,我可以保留一个持久性字典并修改它吗?,python,dictionary,persistence,object-persistence,Python,Dictionary,Persistence,Object Persistence,因此,我想将字典存储在一个持久文件中。有没有一种方法可以使用常规的字典方法来添加、打印或删除该文件中字典中的条目 似乎我可以使用cPickle存储字典并加载它,但我不确定从哪里获取它。当程序加载时从文件中取消pickle,当程序运行时在内存中修改为普通字典,当程序退出时pickle到文件?不确定您还需要什么。如果您的键(不一定是值)是字符串,则标准库模块可以无缝地完成您想要的功能。假设键和值具有repr的工作实现,一种解决方案是保存字典的字符串表示形式(repr(dict))加载到文件。您可以使

因此,我想将字典存储在一个持久文件中。有没有一种方法可以使用常规的字典方法来添加、打印或删除该文件中字典中的条目


似乎我可以使用cPickle存储字典并加载它,但我不确定从哪里获取它。

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

如果您的键(不一定是值)是字符串,则标准库模块可以无缝地完成您想要的功能。

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

1) Is将不适用于具有无法使用的repr实现的类型(或者甚至似乎可以工作,但失败)。你至少需要注意一下正在发生的事情

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


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

酸洗有一个缺点。如果你的字典需要频繁地从磁盘读写,而且它很大,那么它可能会很昂贵。泡菜把东西(整个)倒下来。unpickle(作为一个整体)把东西弄起来

如果你要处理一些小问题,泡菜也可以。如果你想处理更复杂的事情,那就去伯克利。它基本上用于存储键:值对。

我最喜欢的方法(不使用标准python字典函数):使用,总结如下:

创建YAML文件“employment.yml”:

步骤3:用Python阅读

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

现在我的字典里有了所有的值。如果需要动态执行此操作,请创建一个包含YAML的字符串,并使用YAML.safe\u load对其进行解析。

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

使用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加载不会遇到与
shelve
pickle
相同的安全问题,尽管IIRC-it比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

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

您考虑过使用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(),这也会起作用。

阅读pickle文档时,您有什么问题?你能发布一些代码来说明你在做什么,你需要什么帮助吗?基本上,我想把字典作为数据库类型的东西来使用。因此,我可以将字典写入一个文件,然后在需要向字典添加内容时,使用常规字典方法将文件加载到脚本中。是否有一种方法可以加载文件,然后使用典型的dict[“key”]=“items”或del dict[“key”]修改字典?我现在已经试着这么做了,python告诉我在这个特定的例子中dict是未定义的值得注意的是,这不适用于对字典中包含的元素所做的编辑。因此,如果您有一个名为
data
的架子,上面有一个项目列表,那么
data['items'].append(123)
将失败。
ast.literal\u eval()
如果您的dict只包含基本的Python类型。我已经读过,最好将
collections.abc.MutableMapping
子类化,而不是
dict
。如果有人调用
db.setdefault('baz',123)
,当前实现将失败。这篇文章解释了为什么:找到了我要找的东西。有一个性能不相关的用例。谢谢你的回答。这会让人觉得你在回答问题。
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'])