"atexit" --- Exit handlers
**************************

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

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

**Note:** Les fonctions inscrites via ce module ne sont pas appelées
quand le programme est tué par un signal non géré par Python, quand
une erreur fatale interne de Python est détectée, ou quand
"os._exit()" est appelé.

**Note:** The effect of registering or unregistering functions from
within a cleanup function is undefined.

Modifié dans la version 3.7: Quand elles sont utilisées avec des sous-
interpréteurs de l'API C, les fonctions inscrites sont locales à
l'interpréteur dans lequel elles ont été inscrites.

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

   Inscrit *func* comme une fonction à exécuter au moment de l'arrêt
   de l'interpréteur. Tout argument optionnel qui doit être passé à
   *func* doit être passé comme argument à "register()". Il est
   possible d'inscrire les mêmes fonctions et arguments plus d'une
   fois.

   Lors d'un arrêt normal du programme (par exemple, si "sys.exit()"
   est appelée ou l’exécution du module principal se termine), toutes
   les fonctions inscrites sont appelées, dans l'ordre de la dernière
   arrivée, première servie. La supposition est que les modules les
   plus bas niveau vont normalement être importés avant les modules
   haut niveau et ainsi être nettoyés en dernier.

   Si une exception est levée durant l'exécution du gestionnaire de
   fin de programme, une trace d'appels est affichée (à moins que
   "SystemExit" ait été levée) et les informations de l'exception sont
   sauvegardées. Une fois que tous les gestionnaires de fin de
   programme ont eu une chance de s'exécuter, la dernière exception à
   avoir été levée l'est de nouveau.

   Cette fonction renvoie *func*, ce qui rend possible de l'utiliser
   en tant que décorateur.

   Avertissement:

     Starting new threads or calling "os.fork()" from a registered
     function can lead to race condition between the main Python
     runtime thread freeing thread states while internal "threading"
     routines or the new process try to use that state. This can lead
     to crashes rather than clean shutdown.

   Modifié dans la version 3.12: Attempts to start a new thread or
   "os.fork()" a new process in a registered function now leads to
   "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.

Voir aussi:

  Module "readline"
     Useful example of "atexit" to read and write "readline" history
     files.


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

Le simple exemple suivant démontre comment un module peut initialiser
un compteur depuis un fichier quand il est importé, et sauver le
valeur mise à jour du compteur automatiquement quand le programme se
termine, sans avoir besoin que l'application fasse un appel explicite
dans ce module au moment de l'arrêt de l'interpréteur.

   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)

Les arguments positionnels et nommés peuvent aussi être passés à
"register()" afin d'être repassés à la fonction inscrite lors de son
appel :

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

Utilisation en tant que *décorateur* :

   import atexit

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

Ceci fonctionne uniquement avec des fonctions qui peuvent être
appelées sans argument.
