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

バージョン 2.0 で追加.

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


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

注意: このモジュールを使用して登録された関数は、プログラムが 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."

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