简体   繁体   English

将字典存储在文件中以供以后检索

[英]Store a dictionary in a file for later retrieval

I've had a search around but can't find anything regarding this... 我有一个搜索,但找不到任何关于这个......

I'm looking for a way to save a dictionary to file and then later be able to load it back into a variable at a later date by reading the file. 我正在寻找一种方法来保存字典到文件,然后通过读取文件以后能够将其加载回变量。

The contents of the file don't have to be "human readable" it can be as messy as it wants. 文件的内容不必是“人类可读的”,它可能像它想要的那样混乱。

Thanks - Hyflex 谢谢 - Hyflex

EDIT 编辑

import cPickle as pickle

BDICT = {}

## Automatically generated START
name = "BOB"
name_title = name.title()
count = 5
BDICT[name_title] = count

name = "TOM"
name_title = name.title()
count = 5
BDICT[name_title] = count

name = "TIMMY JOE"
name_title = name.title()
count = 5
BDICT[name_title] = count
## Automatically generated END

if BDICT:
    with open('DICT_ITEMS.txt', 'wb') as dict_items_save:
        pickle.dump(BDICT, dict_items_save)

BDICT = {} ## Wiping the dictionary

## Usually in a loop
firstrunDICT = True

if firstrunDICT:
    with open('DICT_ITEMS.txt', 'rb') as dict_items_open:
        dict_items_read = dict_items_open.read()
        if dict_items_read:
            BDICT = pickle.load(dict_items_open)
            firstrunDICT = False
            print BDICT

Error: 错误:

Traceback (most recent call last):
  File "C:\test3.py", line 35, in <module>
    BDICT = pickle.load(dict_items_open)
EOFError

A few people have recommended shelve - I haven't used it, and I'm not knocking it. 有些人建议shelve - 我没有使用它,我也没有敲它。 I have used pickle/cPickle and I'll offer the following approach: 我用过pickle / cPickle,我会提供以下方法:

How to use Pickle/cPickle (the abridged version)... 如何使用Pickle / cPickle(删节版)......

There are many reasons why you would use Pickle (or its noticable faster variant, cPickle). 使用Pickle(或其显着的快速变体cPickle)有很多原因。 Put tersely Pickle is a way to store objects outside of your process. 简洁地说, Pickle是一种在您的流程之外存储对象的方法。

Pickle not only gives you the options to store objects outside your python process, but also does so in a serialized fashion. Pickle不仅为您提供了在python进程之外存储对象的选项,而且还以序列化方式进行。 Meaning, First In, First Out behavior (FIFO). 含义, 先进先出行为(FIFO)。

import pickle

## I am making up a dictionary here to show you how this works...
## Because I want to store this outside of this single run, it could be that this
## dictionary is dynamic and user based - so persistance beyond this run has
## meaning for me.  
myMadeUpDictionary = {"one": "banana", "two": "banana", "three": "banana", "four": "no-more"}

with open("mySavedDict.txt", "wb") as myFile:
    pickle.dump(myMadeUpDictionary, myFile)

So what just happened? 刚刚发生了什么?

  • Step1: imported a module named 'pickle' Step1:导入名为'pickle'的模块
  • Step2: created my dictionary object Step2:创建了我的字典对象
  • Step3: used a context manager to handle the opening/closing of a new file... Step3:使用上下文管理器来处理新文件的打开/关闭...
  • Step4: dump() the contents of the dictionary (which is referenced as 'pickling' the object) and then write it to a file (mySavedDict.txt). Step4:dump()字典的内容(被称为'pickling'对象),然后将其写入文件(mySavedDict.txt)。

If you then go into the file that was just created (located now on your filesystem), you can see the contents. 如果您然后进入刚刚创建的文件(现在位于您的文件系统上),您可以看到内容。 It's messy - ugly - and not very insightlful. 它很混乱 - 丑陋 - 而且不是很有洞察力。

nammer@crunchyQA:~/workspace/SandBox/POSTS/Pickle & cPickle$ cat mySavedDict.txt 
(dp0
S'four'
p1
S'no-more'
p2
sS'three'
p3
S'banana'
p4
sS'two'
p5
g4
sS'one'
p6
g4
s.

So what's next? 下一个是什么?

To bring that BACK into our program we simply do the following: 要将BACK带入我们的程序,我们只需执行以下操作:

import pickle

with open("mySavedDict.txt", "rb") as myFile:
    myNewPulledInDictionary = pickle.load(myFile)

print myNewPulledInDictionary

Which provides the following return: 其中提供以下回报:

{'four': 'no-more', 'one': 'banana', 'three': 'banana', 'two': 'banana'}

cPickle vs Pickle cPickle vs Pickle

You won't see many people use pickle these days - I can't think off the top of my head why you would want to use the first implementation of pickle, especially when there is cPickle which does the same thing (more or less) but a lot faster! 这些天你不会看到很多人使用泡菜 - 我无法想到为什么你会想要使用pickle的第一个实现,特别是当有cPickle做同样的事情时(或多或少)但要快得多!

So you can be lazy and do: 所以你可以懒得做:

import cPickle as pickle

Which is great if you have something already built that uses pickle... but I argue that this is a bad recommendation and I fully expect to get scolded for even recommending that! 如果你已经建立了一些使用泡菜的东西,这是很棒的...但我认为这是一个糟糕的推荐,我完全期望被推荐甚至推荐! (you should really look at your old implementation that used the original pickle and see if you need to change anything to follow cPickle patterns; if you have legacy code or production code you are working with, this saves you time refactoring (finding/replacing all instances of pickle with cPickle). (你应该看看你使用原始pickle旧实现,看看你是否需要改变任何东西来遵循cPickle模式;如果你有遗留代码或生产代码,你可以节省时间重构(查找/替换所有用cPickle泡菜的实例)。

Otherwise, just: 否则,只需:

import cPickle

and everywhere you see a reference to the pickle library, just replace accordingly. 无论你在pickle看到对pickle库的引用,只需相应地替换。 They have the same load() and dump() method. 它们具有相同的load()和dump()方法。

Warning Warning I don't want to write this post any longer than it is, but I seem to have this painful memory of not making a distinction between load() and loads() , and dump() and dumps() . 警告警告我不想再写这篇文章,但我似乎有这种痛苦的记忆,没有区分load()loads()dump()dumps() Damn... that was stupid of me! 该死的......这对我来说是愚蠢的! The short answer is that load()/dump() does it to a file-like object, wheres loads()/dumps() will perform similar behavior but to a string-like object (read more about it in the API, here ). 简短的回答是load()/ dump()将它传递给类似文件的对象,而load()/ dumps()将执行类似的行为,但是对于类似字符串的对象(在API中阅读更多关于它的信息, 这里 )。

Again, I haven't used shelve , but if it works for you (or others) - then yay! 再说一遍,我没有使用shelve ,但如果它对你(或其他人)有效 - 那么就是!

RESPONSE TO YOUR EDIT 回应您的编辑

You need to remove the dict_items_read = dict_items_open.read() from your context-manager at the end. 您需要在dict_items_read = dict_items_open.read()从上下文管理器中删除dict_items_read = dict_items_open.read() The file is already open and read in. You don't read it in like you would a text file to pull out strings... it's storing pickled python objects. 该文件已经打开并读入。您不会像读取文本文件那样读取它...它存储了pickle python对象。 It's not meant for eyes! 它不适合眼睛! It's meant for load(). 它适用于load()。

Your code modified... works just fine for me (copy/paste and run the code below and see if it works). 你的代码修改...对我来说很好(复制/粘贴并运行下面的代码,看看它是否有效)。 Notice near the bottom I've removed your read() of the file object. 注意在底部附近我删除了你对文件对象的read()

import cPickle as pickle

BDICT = {}

## Automatically generated START
name = "BOB"
name_title = name.title()
count = 5
BDICT[name_title] = count

name = "TOM"
name_title = name.title()
count = 5
BDICT[name_title] = count

name = "TIMMY JOE"
name_title = name.title()
count = 5
BDICT[name_title] = count
## Automatically generated END

if BDICT:
    with open('DICT_ITEMS.txt', 'wb') as dict_items_save:
        pickle.dump(BDICT, dict_items_save)

BDICT = {} ## Wiping the dictionary

## Usually in a loop
firstrunDICT = True

if firstrunDICT:
    with open('DICT_ITEMS.txt', 'rb') as dict_items_open:
        BDICT = pickle.load(dict_items_open)
        firstrunDICT = False
        print BDICT

Python has the shelve module for this. Python有这个shelve模块。 It can store many objects in a file that can be opened up later and read in as objects, but it's operating system-dependent. 它可以将许多对象存储在一个文件中,该文件可以在以后打开并作为对象读入,但它依赖于操作系统。

import shelve

dict1 = #dictionary
dict2 = #dictionary

#flags: 
#   c = create new shelf; this can't overwrite an old one, so delete the old one first
#   r = read
#   w = write; you can append to an old shelf
shelf = shelve.open("filename", flag="c")
shelf['key1'] = dict1
shelf['key2'] = dict2

shelf.close()

#reading:
shelf = shelve.open("filename", flag='r')
for key in shelf.keys():
    newdict = shelf[key]
    #do something with it

shelf.close()

你要找的是shelve

You can also use Pickle for this task. 您也可以使用Pickle完成此任务。 Here's a blog post that explains how to do it. 这是一篇博客文章 ,解释了如何做到这一点。

Two functions which create a text file for saving a dictionary and loading a dictionary (which was already saved before) for use again. 两个函数创建一个文本文件,用于保存字典和加载字典(之前已经保存过),以便再次使用。

import pickle

def SaveDictionary(dictionary,File):
    with open(File, "wb") as myFile:
        pickle.dump(dictionary, myFile)
        myFile.close()

def LoadDictionary(File):
    with open(File, "rb") as myFile:
        dict = pickle.load(myFile)
        myFile.close()
        return dict

These functions can be called through : 这些功能可通过以下方式调用:

SaveDictionary(mylib.Members,"members.txt") # saved dict. in a file
members = LoadDictionary("members.txt")     # opened dict. of members

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM