python中酸洗的问题-程序退出后项目不保存到文件中

Posted

技术标签:

【中文标题】python中酸洗的问题-程序退出后项目不保存到文件中【英文标题】:Issues with pickling in python - items not saving to file once program exits 【发布时间】:2018-03-28 03:34:41 【问题描述】:

我正在尝试创建一个 python 程序来保存我朋友的生日并轻松访问它们并每天检查生日(我不擅长记住日期而且我从不使用 facebook),但是当我添加一个新的生日时只能在我结束程序之前访问 - 然后它再次消失。我已经为此苦苦挣扎了一段时间,非常感谢帮助修复错误。谢谢!

import time
import pickle
def main():
        birthday_file = open('birthdays_dict.dat','ab')
        birthday_doc = open('birthdays_dict.dat','rb')
        birthdays = pickle.load(birthday_doc)
        date = time.strftime("%m/%d")
        again = 'y'
        while again.lower() == 'y' or again.lower() == 'yes':
                choice = menu_choice()
                if choice == 1:
                        name = add_name()
                        birthday = add_birthday()
                        birthdays[name] = birthday
                        print(name)
                        print(birthday)
                        pickle.dump(birthdays,birthday_file)
                elif choice == 2:
                        print('Birthdays today(' + date + '):')
                        birth_today = 
                        for key, value in birthdays.items():
                                if value == date:
                                        print(key)
                elif choice == 3:
                        search_name = input('Enter name to search: ')
                        print()
                        if search_name in birthdays:
                                print(birthdays[search_name])
                                if birthdays[search_name] == date:
                                        print('Their birthday is today!')
                        else:
                                print('Not found')
                else:
                        print('Not a valid selection!')
                print()
                again = go_again()
        birthday_file.close()
        birthday_doc.close()

【问题讨论】:

这可能不是您的问题(尽管如果您在 Windows 上可能会出现问题?),但您可能不想像那样同时打开同一个文件两次.以读取模式打开它pickle.load,关闭它,然后以附加模式打开它。 另外,您可能想查看标准库中的 [shelve](docs.python.org/3/library/shelve.html) 模块。这是一个超级简单的数据库,就像一个字典,但是在磁盘上,这正是你想要的。 IIRC,键必须是字符串,但值可以是任何可以腌制的东西,这对你来说应该很好。 还有一件事可能不是问题,但仍然值得做:您应该使用with open(…) as birthday_file: 语句而不是最后手动调用close。这样,如果您的程序被意外错误或 ^C 等中断,文件仍然会关闭。 (如果您在退出前不关闭文件,有时最后的写入块可能会丢失。) @abarnert 谢谢! [搁置]是我肯定会尝试熟悉的东西。同时,我尝试按照建议的方式更改文件打开方式,但退出后仍然无法保存任何内容。我不确定问题是我打开/关闭文件的方式还是我转储文件的方式。我知道这个程序相当简单,但我还在学习,这个错误让我把头撞到墙上哈哈 【参考方案1】:

您的问题是您一直在文件上附加新的 dicts 而不是替换旧的,但是在启动时您只加载第一个而不是全部。


要解决此问题,您需要进行更改:

birthday_file = open('birthdays_dict.dat','ab')

…到这个:

birthday_file = open('birthdays_dict.dat','wb')

但不要自行更改,因为这会在您阅读旧版本之前删除文件!


你可能想在函数的顶部做这样的事情:

with open('birthdays_dict.dat', 'rb') as birthday_doc:
    birthdays = pickle.load(birthday_doc)

我使用了with 语句,所以文件会在load 之后自动关闭,所以我们以后覆盖它绝对安全。

然后,当您想写入文件时,您可以在w 模式下打开它以擦除文件并用新版本覆盖它——此时您最好立即关闭它,因为如果你曾经再次写过它,你会想先再次擦除它,所以让我们再次使用with

with open('birthdays_dict.dat', 'wb') as birthday_doc:
    pickle.dump(birthdays, birthday_doc)

【讨论】:

@abarnet 这完全解决了!非常感谢您的帮助!我认为我的困惑在于我在编码时就好像我在附加字典,而不是每次都用新版本的字典覆盖它……哎呀。我非常感谢您为解释这一点所付出的帮助和努力。酸洗是我在 python 中一直在努力解决的新问题,并且在感觉如此简单的事情上反复失败开始变得令人难以置信的沮丧。 (尤其是一个感觉如此重要的主题!)

以上是关于python中酸洗的问题-程序退出后项目不保存到文件中的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中解释 Dill 的酸洗跟踪输出? (分析(非)酸洗/(反)序列化瓶颈)

如何使用 python 多线程并行化来自另一个模块的函数而不进行酸洗?

在装饰器中使用 ProcessPoolExecutor 酸洗 Python 函数失败

带有 RPYC 的多处理 Python “ValueError:酸洗已禁用”

Python 酸洗错误:TypeError:对象泡菜未返回列表。 numpy的问题?

Python酸洗EOF问题