简体   繁体   English

使用Python的pickle打开并保存字典

[英]Using Python's pickle to open and save a dictionary

In the final days of my intro comp sci class, we got to creating dictionaries. 在我的intro comp sci课程的最后几天,我们开始创建词典。 A homework program in our book asks us to create something that can look up, add, change, and delete a set of names and email addresses. 我们书中的家庭作业程序要求我们创建可以查找,添加,更改和删除一组名称和电子邮件地址的内容。 It asks us to pickle the dictionary, but the kicker for me is that it stipulates that each time the program starts, it should retrieve the dictionary from the file and unpickle it. 它要求我们挑选字典,但对我而言,它是规定每次程序启动时,它应该从文件中检索字典并取消它。 I don't know if I coded myself into a corner, but I can't figure out how to do this with what I've done so far. 我不知道我是否将自己编入角落,但我无法弄清楚到目前为止我是如何做到这一点的。

My code: 我的代码:

import mMyUtils
import pickle
LOOK_UP = 1
ADD = 2
CHANGE = 3
DELETE = 4
QUIT = 5

def main():
    emails = {}
    choice = 0
    while choice != QUIT:
        choice = getMenuChoice()
        if choice == LOOK_UP:
            lookUp(emails)
        elif choice == ADD:
            add(emails)
        elif choice == CHANGE:
            change(emails)
        elif choice == DELETE:
            delete(emails)
        else:
            exit

def getMenuChoice():
    print()
    print('Name and Email Address Catalog')
    print('------------------------------')
    print('1. Look up an email address')
    print('2. Add a new email address')
    print('3. Change an email address')
    print('4. Delete an email address')
    print('5. Quit the program')
    print()

    choice = int(input('Enter the choice: '))
    while choice < LOOK_UP or choice > QUIT:
        choice = int(input('Enter a valid choice: '))

    return choice

def lookUp(emails):
    name = input('Enter a name: ')
    print(emails.get(name, 'Not found.'))

def add(emails):
    name = input('Enter a name: ')
    address = input('Enter an email address: ')
    if name not in emails:
        emails[name] = address
        pickle.dump(emails, open("emails.dat", "wb"))
    else:
        print('That entry already exists.')

def change(emails):
    name = input('Enter a name: ')
    if name in emails:
        address = input('Enter the new address: ')
        emails[name] = address
        pickle.dump(emails, open("emails.dat", "wb"))
    else:
        print('That name is not found.')

def delete(emails):
    name = input('Enter a name: ')
    if name in emails:
        del emails[name]
    else:
        print('That name is not found.')

main()

I know I should set my emails variable to be some form of pickle.load, but I can't figure it out for the life of me. 我知道我应该将我的电子邮件变量设置为某种形式的pickle.load,但我无法弄清楚我的生活。 mMyUtils is a library I made for try/except logic, I'll put that in once I get the new stuff working. mMyUtils是我为try / except逻辑创建的库,我会把它放在一次我得到新的东西工作。

If you're saving the dictionary like so: 如果你像这样保存字典:

pickle.dump(emails, open('emails.dat', 'wb'))

The following will load it back: 以下将加载它:

emails = pickle.load(open('emails.dat', 'rb'))

You must load the file and unpickle the data before you can access it, change lookUp() to this: 您必须先加载文件并lookUp()数据,然后才能访问它,将lookUp()更改为:

def lookUp(emails):
    with open("emails.dat", "rb") as fo:
        emails = pickle.load(fo)

    name = input('Enter a name: ')
    print(emails.get(name, 'Not found.'))

Consider yourself using ast.literal_eval instead of pickle: http://docs.python.org/2/library/ast.html#ast.literal_eval 考虑自己使用ast.literal_eval而不是pickle: http ://docs.python.org/2/library/ast.html#ast.literal_eval

>>>import ast
>>> print mydict
{'bob': 1, 'danny': 3, 'alan': 2, 'carl': 40}
>>> string="{'bob': 1, 'danny': 3, 'alan': 2, 'carl': 40}"
>>> type(string)
<type 'str'>
>>> type( ast.literal_eval(string) )
<type 'dict'>

To save/read dict from file, you can do it like with normal string. 要从文件中保存/读取dict,可以像使用普通字符串一样进行。

The problem was, and I guess I didn't emphasis it enough, was what I was supposed to do if the dictionary didn't exist in the first place. 问题是,我想我没有足够强调,如果字典首先不存在,我本来应该做的。 The design doc states that you should load the dictionary every time you run the program. 设计文档声明每次运行程序时都应加载字典。 Well if you're running the program for the first time, you don't have a dictionary to load, leading to an error. 好吧,如果你是第一次运行程序,你没有要加载的字典,导致错误。 I got around this by basically doing the function twice using try/except. 我通过使用try / except基本上执行该功能两次来解决这个问题。

My code: 我的代码:

import mMyUtils
import pickle
import dictionaryGenerator
LOOK_UP = 1
ADD = 2
CHANGE = 3
DELETE = 4
QUIT = 5

def main():
    hasError = False
    try:
        emails = pickle.load(open('emails.dat', 'rb'))
        choice = 0
        while choice != QUIT:
            choice = getMenuChoice()
            if choice == LOOK_UP:
                lookUp(emails)
            elif choice == ADD:
                 add(emails)
            elif choice == CHANGE:
                change(emails)
            elif choice == DELETE:
                delete(emails)
            else:
                print("Good-bye!")
                exit
    except Exception as err:
        hasError = True
        mMyUtils.printError("Error: no such file",err)
        mMyUtils.writeToErrorLog()

    finally:
        if hasError:
            emails = {}
        choice = 0
        while choice != QUIT:
            choice = getMenuChoice()
            if choice == LOOK_UP:
                lookUp(emails)
            elif choice == ADD:
                add(emails)
            elif choice == CHANGE:
                change(emails)
            elif choice == DELETE:
                delete(emails)
            else:
                print("Good-bye!")
                exit





def getMenuChoice():
    print()
    print('Name and Email Address Catalog')
    print('------------------------------')
    print('1. Look up an email address')
    print('2. Add a new email address')
    print('3. Change an email address')
    print('4. Delete an email address')
    print('5. Quit the program')
    print()

    choice = int(input('Enter the choice: '))
    while choice < LOOK_UP or choice > QUIT:
        choice = int(input('Enter a valid choice: '))

    return choice

def lookUp(emails):

    name = input('Enter a name: ')
    print(emails.get(name, 'Not found.'))

def add(emails):
    name = input('Enter a name: ')
    address = input('Enter an email address: ')
    if name not in emails:
        emails[name] = address
        with open("emails.dat",  "wb") as infile:
            pickle.dump(emails, infile)

    else:
        print('That entry already exists.')

def change(emails):
    name = input('Enter a name: ')
    if name in emails:
        address = input('Enter the new address: ')
        emails[name] = address
        with open("emails.dat", "wb") as infile:
            pickle.dump(emails, infile)

    else:
        print('That name is not found.')

def delete(emails):
    name = input('Enter a name: ')
    if name in emails:
        del emails[name]
    else:
        print('That name is not found.')

main()

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

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