仅在抛出异常时清理对象

3 投票
1 回答
626 浏览
提问于 2025-04-17 03:51

我需要在对一个文件进行操作时,如果这些操作没有全部成功,就把这个文件删除(也就是说,如果出现了异常)。本来可以简单地用 except: 来处理,删除文件后再抛出异常,但这样的话,如果因为某些奇怪的原因文件无法删除,原来的异常信息就会丢失。

我目前想到的最好办法是这样的:

try:
    file_path = "whatever.jpg"
    # do stuff with file
except:
    exception_raised = True
    raise
finally:
    try:
        if exception_raised:
            os.unlink(file_path)
    except:
        pass

return file_path   # everything OK

有没有人知道更好、更符合Python风格的方法?

1 个回答

5

另一种选择是,如果你不想丢失异常信息,可以简单地将其保存起来:

Python 3.x 版本:

try:
    file_path = "whatever.jpg"
    # do stuff with file
except BaseException as e:
    try:
        os.unlink(file_path)
    except Exception:
        traceback.print_exc()
    raise e

Python 2.x 版本稍微复杂一些,因为你需要手动保存完整的异常信息(否则你会丢失错误追踪信息):

try:
    file_path = "whatever.jpg"
    # do stuff with file
except:
    e = sys.exc_info()
    try:
        os.unlink(file_path)
    except Exception:
        traceback.print_exc()
    raise e[0], e[1], e[2]

编辑:在内部的 try 块中,只捕获 Exception 的子类,因为你不想在这里捕获 SystemExitKeyboardInterrupt。同时,报告在解除链接时发生的任何异常,而不是简单地忽略它。

撰写回答