结束前的倔强
结束前的倔强
有时候我们希望在程序执行一些函数,比如通知或者妥善处理一些善后工作,可以实现的方法很多,比如借助异常、with 或者合理的函数布局都可以。Python 提供了一种更加优雅的做法—— atexit 模块。
atexit 模块提供的接口非常简单:
- atexit.register(func, *args, **kwargs) 注册回调函数
- atexit.unregister(func) 撤销回调函数
非常简单,其中 func 参数是函数对象,kwargs 参数会作为回调函数执行时的参数。
简单的例子
import atexit
def on_exit(*args):
print("I'm quiting.", args)
atexit.register(on_exit)
atexit.register(on_exit, "I will miss you!")
# this will unregister all on exit callbacks named 'on_exit'
#atexit.unregister(on_exit)
print("Start.")
print("End.")
上面代码的执行结果:
Start.
End.
I'm quiting. ('I will miss you!',)
I'm quiting. ()
可以看到在 “End” 之后,两个 callback 被执行了,但是逆序执行。
原理
在 atexit 的实现中,将所有注册函数对象连接在一起,退出前逆序依次执行所有回调函数。也可以认为回调函数链表总是在头部插入最新的记录。如果我们在注册了上面两个回调后,再注册一个 new_callback() ,callback 链表看起来会是这样。

撤销回调
atexit.unregister 会撤销函数对象的所有回调,对于前面的代码,会取消两个 on_exit 回调,再次上面的代码只会输出:
Start.
End.
装饰器注册
除了经典的 atexit.register 接口注册回调函数外,atexit.register 还可以用装饰器风格注册回调。
import atexit
@atexit.register