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."

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