说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gr99123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Python 的 atexit 模块定义了清理函数的注册和反注册函数. 被注册的函数会在解释器正常终止时执行。atexit 会按照注册顺序的逆序执行; 如果你注册了 A, B 和 C, 那么在解释器终止时会依序执行 C, B, A。
Python里atexit,和Unix系统是同一个机制。 在程序的任何地方都可以注册一个或多个回调函数,在程序退出时执行。
atexit 模块只有两个方法:
回调顺序为先进后出,应该是一个栈结构。语法为:
atexit.register(func, *args, **kwargs)
将 func 注册为终止时执行的函数. 任何传给 func 的可选的参数都应当作为参数传给 register(). 可以多次注册同样的函数及参数.
在正常的程序终止时 (举例来说, 当调用了 sys.exit() 或是主模块的执行完成时), 所有注册过的函数都会以后进先出的顺序执行. 这样做是假定更底层的模块通常会比高层模块更早引入, 因此需要更晚清理.
如果在 exit 处理句柄执行期间引发了异常,将会打印回溯信息 (除非引发的是 SystemExit) 并且异常信息会被保存。 在所有 exit 处理句柄都获得运行机会之后,所引发的最后一个异常会被重新引发。
这个函数返回 func 对象,可以把它当作装饰器使用。
支持装饰器:
import atexit
@atexit.register
def foo():
print('我走了。')
# 我走了。
语法为:atexit.unregister(func)
。
将 func 移出当解释器关闭时要运行的函数列表。 如果 func 之前未被注册则 unregister() 将静默地不做任何事。 如果 func 已被注册一次以上,则该函数每次在 atexit 调用栈中的出现都将被移除。 当取消注册时会在内部使用相等性比较 (==),因而函数引用不需要具有匹配的标识号。
除了以上两个主要方法外,还有以下几个方法:
# 清除以前注册的退出功能列表
atexit._clear()
# 返回已注册的退出函数数
atexit._ncallbacks() # 1
# 运行所有注册的退出功能。
# 如果callaback引发异常,与 sys.unraisablehook 记录相同
atexit._run_exitfuncs()
# 我走了。
通过该模块注册的函数, 在程序被未被 Python 捕获的信号杀死时并不会执行, 在检测到 Python 内部致命错误以及调用了 os._exit()
时也不会执行。
虽然无论是正常退出、还是异常退出(返回值非0),这个机制都会被触发; 但是,在被杀掉时——比如Ctrl+c,或kill -9等场景,是被外部信号(signal)控制退出——都是不会生效的。
此模块的方法不适用于交互式执行环境,如 jupyter 等。
以下是使用场景:
注意,场景是解释器正常终止。
简单的写法,不侵入业务代码。
import time
import atexit
start = time.time()
atexit.register(lambda: print('用时(秒):', time.time()-start))
time.sleep(3)
print('hello!')
'''
hello!
用时(秒): 3.0034449100494385
'''
在同目录下会生成一个 counterfile 文件,执行脚本三次,文件中的值为 3。
try:
with open('counterfile') as infile:
_count = int(infile.read())
except FileNotFoundError:
_count = 0
def incrcounter(n):
global _count
_count = _count + n
def savecounter():
with open('counterfile', 'w') as outfile:
outfile.write('%d' % _count)
# 每次执行加1
incrcounter(1)
import atexit
atexit.register(savecounter)
要注意的是,同一个函数注册两次,会执行两次。
def goodbye(name, adjective):
print('Goodbye %s, it was %s to meet you.' % (name, adjective))
import atexit
atexit.register(goodbye, 'Donny', 'nice')
# or:
atexit.register(goodbye, adjective='nice', name='Donny')
'''
Goodbye Donny, it was nice to meet you.
Goodbye Donny, it was nice to meet you.
'''
只有在函数不需要任何参数调用时才能工作。
import atexit
@atexit.register
def goodbye():
print('You are now leaving the Python sector.')
更新时间:2022-05-01 10:44:37 标签:python 退出