我最终必须编写并支持具有以下高级结构的短python包装器脚本:
try:
code
...
...
except:
raise
finally:
file_handle.close()
db_conn.close()
请注意,我在except
块中所做的只是将异常重新引发到脚本调用者 sans window-dressing;这在我的特定背景下不是问题。这里的想法是清理代码应始终通过finally
块执行,异常与否。
为此,我最好使用atexit
处理程序吗?我可以在没有try
引入的额外缩进级别的情况下完成。
答案 0 :(得分:4)
atexit
模块提供了一个简单的接口,用于在程序正常关闭时注册要调用的函数。注册的函数在正常的解释器终止时自动执行。
import atexit
def cleanup():
print 'performimg cleanup'
# multiple functions can be registered here...
atexit.register(cleanup)
sys模块还提供了一个hook,sys.exitfunc,但只能在那里注册一个函数。
Finally
附带try except
块,finally
的功能也可以用于类似清理的内容,但是在finally
块中sys.exc_info是all-None
如果finally子句引发另一个异常,则会丢弃已保存的异常,但是您可以将try除了在atexit
注册的函数中处理它们。
另一个pro-con
是atexit
函数仅在程序终止时执行,但是您可以在代码中的任何位置使用finally
(使用try-except)并执行清理
在您的场景中,您想要从清理内容中引发异常,如果您可以在程序结束时进行清理,那么使用atexit
会很有帮助
答案 1 :(得分:1)
atexit
,因此这不是您要查找的内容。
答案 2 :(得分:1)
只需使用contextlib.closing
with closing(resource1) as f1, closing(resource2) as f2:
f1.something()
f2.something()
他们将自动关闭。文件对象可以直接用作上下文,因此您不需要closing
调用。
如果close
不是资源使用的唯一方法,则可以使用contextlib.contextmanager
装饰器创建自定义函数。