# 29.8. `atexit` - 退出处理程序

`atexit`模块定义了注册和注销清除函数的函数。这样注册的函数在正常解释器终止时自动执行。`atexit` 运行这些函数以它们注册顺序 逆向 顺序运行; 当你注册 `A`, `B`, 和`C`, 解释器结束时他们的运行顺序是: `C`, `B`, `A`.

注意：当检测到Python致命内部错误时，或当`os._exit()`。

`atexit.``register`(func, *args, **kargs)

  将func寄存器作为要在终止时执行的函数。任何传递给func的可选参数必须作为参数传递给`register()`。可以多次注册相同的函数和参数。

  在正常的程序终止（对于实例，如果`sys.exit()`被调用或主模块的执行完成），所有注册的函数以最后进先出的顺序调用。假设较低级别模块通常在较高级别模块之前导入，因此必须以后进行清理。

  如果在执行退出处理程序期间引发异常，则会打印回溯（除非引发`SystemExit`），并保存异常信息。在所有退出处理程序有机会运行后，最后一个异常被提出是重新提出。

  此函数返回func，这使得它可以用作装饰器。

`atexit.``unregister`(func)

  从要在解释器关机运行的函数列表中删除func。调用`unregister()`后，即使解释器关闭，即使注册了多次，也保证不会调用func。`unregister()`如果func之前未注册，则默认不执行任何操作。

也可以看看

模块`readline`
  `atexit`读取和写入`readline`历史记录文件的有用示例。

## 29.8.1. `atexit`示例

以下简单示例演示了模块如何在导入时从文件初始化计数器，并在程序终止时自动保存计数器的更新值，而不依赖于在终止时明确调用该模块的应用程序。

    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)

    import atexit
    atexit.register(savecounter)

位置和关键字参数也可以传递到`register()`，以便在调用时传递给注册函数：

    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')

用作decorator：

    import atexit

    @atexit.register
    def goodbye():
        print("You are now leaving the Python sector.")

这只适用于可以在没有参数的情况下调用的函数。