Python中的MemoryError导致空的pickle文件

0 投票
1 回答
2271 浏览
提问于 2025-04-18 17:51

我正在做一个图书馆类型的借书/还书系统。当用户点击 exit 时,程序会调用一个 close_window 函数,这个函数会在窗口关闭之前把当前的字典对象保存到一个叫做 pickle 的文件里。

def close_window(self):
    if messagebox.askokcancel("Quit", "You want to close the program now?"):
        patrons.dump_data()

        self.master.destroy()

当程序再次启动时,它会调用一个 load_data 函数来加载这些保存的文件。不过,我在退出系统时遇到了 MemoryError,并且其中一个保存的文件被覆盖成了一个空文件。根据文档,我了解到 MemoryError 是因为程序创建了太多对象,导致内存不够用。我不太明白为什么会这样,因为我处理的数据并不大。被覆盖的那个文件只有 1 KB。

我该如何确保在发生 MemoryError 时,我的保存文件不会被覆盖成空文件呢?这可能会导致严重的数据丢失。我刚开始学习编程,这个项目是我学习的一个方式。也许我做错了什么导致了内存错误,或者我可能需要更多的电脑内存。无论如何,不管有没有内存错误,覆盖一个保存的文件成空文件都是不合理的。

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python34\lib\tkinter\__init__.py", line 1487, in __call__
    return self.func(*args)
  File "C:/Python34/Lib/site-packages/toolkit/main.py", line 435, in close_window
    patrons.dump_data()
  File "C:\Python34\Lib\site-packages\toolkit\patrons.py", line 20, in dump_data
    pickle.dump(patronslist, f)
MemoryError

这个错误在Python 中序列化数据时的 MemoryError中有部分讨论。不过在这里,我得到的是一个空文件,甚至连部分文件都没有。我想知道有没有解决这个问题的办法。也许可以先把序列化的数据保存到一个临时文件里。如果在保存时没有发生内存错误,那么可以用临时文件来覆盖永久文件(但这可能又会引发另一个 MemoryError,对吧?)。

我使用的是 Win7 x86,3 GB 内存,Python 3.4.1

1 个回答

1

根据Gerrat上面的评论,我在想下面这种做法是否不错:

patrons.py
def dump_data():
    with open("./pickled_dicts/temp_patrons.pkl", 'wb') as f:
        global patronslist
        pickle.dump(patronslist, f)


main.py
def close_window(self):
    if messagebox.askokcancel("Quit", "You want to close the program now?"):
        try:
            patrons.dump_data()
            os.remove("./pickled_dicts/patrons.pkl")
            os.rename("./pickled_dicts/temp_patrons.pkl", "./pickled_dicts/patrons.pkl")
        except MemoryError:
            messagebox.showerror("Memory Problem", "Your computer experienced memory problem. Your last session was not saved.")     
        self.master.destroy()

基本上,我首先把字典对象保存到一个临时文件(temp_patrons.pkl),然后如果没有出现MemoryError(内存错误),就把这个临时文件重命名为我的永久文件(patrons.pkl)。如果出现了MemoryError,那么原来的patrons.pkl文件就会保留下来。

撰写回答