# 28.9. `atexit` --- 終了ハンドラ

バージョン 2.0 で追加.

ソースコード: Lib/atexit.py

`atexit` モジュールは、クリーンアップ関数の登録を行う関数を定義します。登録された関数はインタプリタの通常終了時に自動的に実行されます。`atexit` はそれら関数を登録した順と 逆に 実行します; `A`、`B`、`C` の順に登録した場合、インタプリタ終了時に `C`、`B`、`A` の順に実行されます。

注意: このモジュールを使用して登録された関数は、プログラムが Python が扱わないシグナルによって kill された場合、Python 内部で致命的なエラーが検出された場合、あるいは `os._exit()` が呼び出された場合は実行されません。

このモジュールは、 `sys.exitfunc` 変数の提供していた機能の代用となるインタフェースです。

注意: `sys.exitfunc` を設定する他のコードとともに使用した場合には、このモジュールは正しく動作しないでしょう。特に、他のコア Python モジュールでは、プログラマの意図を知らなくても `atexit` を自由に使えます。 `sys.exitfunc` を使っている人は、代わりに `atexit` を使うコードに変換してください。 `sys.exitfunc` を設定するコードを変換するには、 `atexit` を import し、 `sys.exitfunc` へ束縛されていた関数を登録するのが最も簡単です。

`atexit.``register`(func[, *args[, **kwargs]])

  func を終了時に実行する関数として登録します。func に渡す引数は `register()` の引数として指定しなければなりません。同じ関数を同じ引数で複数回登録できます。

  通常のプログラムの終了時、例えば `sys.exit()` が呼び出されるとき、あるいは、メインモジュールの実行が完了したときに、登録された全ての関数を、最後に登録されたものから順に呼び出します。通常、より低レベルのモジュールはより高レベルのモジュールより前に import されるので、後で後始末が行われるという仮定に基づいています。

  終了ハンドラの実行中に例外が発生すると、(`SystemExit` 以外の場合は)トレースバックを表示して、例外の情報を保存します。全ての終了ハンドラに動作するチャンスを与えた後に、最後に送出された例外を再送出します。

  バージョン 2.6 で変更: この関数は func を返すようになったので、これをデコレータとして利用できます。

参考

`readline` モジュール

  `readline` ヒストリファイルを読み書きするための `atexit` の有用な例です。

## 28.9.1. `atexit` の例

次の簡単な例では、あるモジュールを import した時にカウンタを初期化しておき、プログラムが終了するときにアプリケーションがこのモジュールを明示的に呼び出さなくてもカウンタが更新されるようにする方法を示しています。

    try:
        _count = int(open("counter").read())
    except IOError:
        _count = 0

    def incrcounter(n):
        global _count
        _count = _count + n

    def savecounter():
        open("counter", "w").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')

デコレータ として利用する例:

    import atexit

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

デコレータとして利用できるのは、その関数が引数なしで呼び出された場合に限られます。