"atexit" --- 終了ハンドラー
***************************

======================================================================

The "atexit" module defines functions to register and unregister
cleanup functions.  Functions thus registered are automatically
executed upon normal interpreter termination.  "atexit" runs these
functions in the *reverse* order in which they were registered; if you
register "A", "B", and "C", at interpreter termination time they will
be run in the order "C", "B", "A".

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

**注意:** クリーンアップ関数内からの関数の登録・登録解除効果は定義され
ていません。

バージョン 3.7 で変更: C-API のサブインタープリタで使われているとき、
登録された関数は登録先のインタープリタのローカルな関数になります。

atexit.register(func, *args, **kwargs)

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

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

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

   この関数は *func* を返し、これをデコレータとして利用できます。

   警告:

     登録された関数から新しいスレッドを開始したり、 "os.fork()" を呼び
     出したりすると、メインの Python ランタイムスレッドがスレッド状態
     を開放する一方で、内部の "threading" ルーチンや新しいプロセスがそ
     のスレッド状態を使用しようと試みる競合が発生します。これはクリー
     ンなシャットダウンではなく、クラッシュにつながる恐れがあります。

   バージョン 3.12 で変更: 登録された関数から新しいスレッドの開始また
   は新しいプロセスの "os.fork()" が試みられた場合は、 "RuntimeError"
   が発生するようになりました。

atexit.unregister(func)

   Remove *func* from the list of functions to be run at interpreter
   shutdown. "unregister()" silently does nothing if *func* was not
   previously registered.  If *func* has been registered more than
   once, every occurrence of that function in the "atexit" call stack
   will be removed.  Equality comparisons ("==") are used internally
   during unregistration, so function references do not need to have
   matching identities.

参考:

  "readline" モジュール
     Useful example of "atexit" to read and write "readline" history
     files.


"atexit" Example
================

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

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

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

   import atexit

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

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