"atexit" --- Manipuladores de saída
***********************************

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

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

**Nota:** As funções registradas através deste módulo não são
invocadas quando o programa é morto por um sinal não tratado pelo
Python, quando um erro interno fatal do Python é detectado ou quando a
função "os._exit()" é invocada.

**Nota:** O efeito de registrar ou cancelar o registro de funções
dentro de uma função de limpeza é indefinido.

Alterado na versão 3.7: Quando usadas com os subinterpretadores de
C-API, as funções registradas são locais para o interpretador em que
foram registradas.

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

   Registre *func* como uma função a ser executada no término.
   Qualquer o argumento opcional que deve ser passado para *func* for
   passado como argumento para "register()". É possível registrar mais
   ou menos a mesma função e argumentos.

   Na terminação normal do programa (por exemplo, se "sys.exit()" for
   chamado ou a execução do módulo principal for concluída), todas as
   funções registradas serão chamadas por último, pela primeira ordem.
   A suposição é que os módulos de nível inferior normalmente serão
   importados antes dos módulos de nível mais alto e, portanto, devem
   ser limpos posteriormente.

   Se uma exceção é levantada durante a execução dos manipuladores de
   saída, um traceback é impresso (a menos que "SystemExit" seja
   levantada) e as informações de exceção sejam salvas. Depois de
   todos os manipuladores de saída terem tido a chance de executar a
   última exceção a ser levantada, é levantada novamente.

   Esta função retorna *func*, o que torna possível usá-la como um
   decorador.

   Aviso:

     Iniciar novas threads ou chamar "os.fork()" de uma função
     registrada pode levar a uma condição de corrida entre os estados
     de thread de liberação de thread principal do tempo de execução
     do Python enquanto as rotinas internas "threading" ou o novo
     processo tentam usar esse estado. Isso pode levar a travamentos
     em vez de desligamento normal.

   Alterado na versão 3.12: Tentativas de iniciar uma nova thread ou
   "os.fork()" um novo processo em uma função registrada agora leva a
   "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.

Ver também:

  Módulo "readline"
     Useful example of "atexit" to read and write "readline" history
     files.


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

O exemplo simples a seguir demonstra como um módulo pode inicializar
um contador de um arquivo quando ele é importado e salvar
automaticamente o valor atualizado do contador quando o programa
termina, sem depender que a aplicação faça uma chamada explícita nesse
módulo na finalização.

   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)

Os argumentos posicional e de palavra reservada também podem ser
passados para "register()" para ser passada para a função registrada
quando é chamada

   def goodbye(name, adjective):
       print('Goodbye %s, it was %s to meet you.' % (name, adjective))

   import atexit

   atexit.register(goodbye, 'Donny', 'nice')
   # ou:
   atexit.register(goodbye, adjective='nice', name='Donny')

Utilizado como um *decorador*:

   import atexit

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

Isso só funciona com funções que podem ser invocadas sem argumentos.
