在清理时使用__del__保存状态到文件?

1 投票
4 回答
876 浏览
提问于 2025-04-16 20:15

我有一个类,长得像这样:

class A:
    def __init__(self, filename, sources):
        # gather info from file
        # info is updated during lifetime of the object

    def close(self):
        # save info back to file

现在,这个类是在一个服务器程序里,所以它可能会在没有提前通知的情况下被信号关闭。这样定义它,能确保这个类尽可能保存它的信息,安全吗?

def __del__(self):
    self.close()

如果不安全,你有什么建议的解决方案吗?

4 个回答

1

为了确保程序在结束时能够有序地清理资源,你可以使用 sys.atexit 这个功能。你可以在这里注册一个函数,这个函数会调用你的关闭方法。需要注意的是,某个对象的清理方法在程序结束时可能不会被自动调用。

1

不,你永远都不安全。

如果操作系统想要在没有任何通知的情况下终止你的程序,它是可以做到的。你对此无能为力。你的程序可能在任何指令后、任何时候停止运行,根本没有机会执行其他代码。

没有办法保护你的服务器不受到终止信号的影响。

如果你愿意,可以捕捉一些较小的信号,然后手动删除你的对象,强制调用 close()

2

等到以后再处理并不是让事情变得可靠的好办法。其实,你应该采取完全相反的做法。只要你知道某些东西需要保存,就应该立刻采取行动去保存它。为了让它变得可靠,你首先需要把在尝试保存更改时可能出现的失败情况的恢复步骤写到硬盘上。

class A:
    def __init__(self, filename, sources):
        self.recover()
        # gather info from file
        # info is updated during lifetime of the object

    def update_info(self, info):
        # append 'info' to recovery_log
        # recovery_log.flush()
        # write 'info' to file
        # file.flush()
        # append 'info-SUCCESS' to recover_log
        # recovery_log.flush()

    def recover(self):
        # open recovery_log
        # skip to last 'info-SUCCESS'
        # read 'info' from recover_log
        # write 'info' to file
        # file.flush()
        # append 'info-SUCCESS' to recover_log
        # recovery_log.flush()

这里最重要的是,recover() 每次都会执行,并且每一步之后都要跟着一个 flush(),这样才能确保数据在进行下一步之前已经写入硬盘。还有一个重要的点是,恢复日志本身只会进行追加操作,绝不会以任何方式覆盖,这样日志中的数据就不会损坏。

撰写回答