Python中的MemoryError导致空的pickle文件

时间:2014-08-19 21:38:58

标签: python memory python-3.x pickle

我正在开发一个图书馆式结帐/签到系统。当用户单击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函数来加载pickle文件。不知何故,我在退出系统时遇到了MemoryError,其中一个pickle文件被一个空文件覆盖了。从the documentation开始,我认为当程序创建太多对象并且内存不足时会发生MemoryError。我不知道为什么在我的情况下发生了这种情况,因为我没有处理大数据。被覆盖的pickle文件只有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

MemoryError while pickling data in python部分讨论了此错误。在这里,我得到一个空文件,甚至不是部分文件。我想知道这个问题是否有解决方法。也许将pickle数据保存到临时文件中。如果在保存期间没有发生内存错误,则可以使用临时文件覆盖永久文件(但这可能会触发另一个MemoryError权限?)。

我运行Win7 x86,3 GB RAM,Python 3.4.1

1 个答案:

答案 0 :(得分: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),该文件重命名为我的永久文件(patrons.pkl),假定没有MemoryError。如果MemoryError,则原始patrons.pkl仍然存在。