# `atexit` — Manipuladores de saída

O módulo `atexit` define funções para registrar e cancelar o registro de funções de limpeza. As funções assim registradas são executadas automaticamente após a conclusão normal do interpretador. O módulo `atexit` executa essas funções na ordem reversa na qual foram registradas; se você inscrever `A`, `B` e `C`, no momento do término do interpretador, eles serão executados na ordem `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 da lista de funções a serem executadas no desligamento do interpretador. `unregister()` silenciosamente não faz nada se func não foi registrado anteriormente. Se func foi registrado mais de uma vez, cada ocorrência dessa função na pilha de chamada `atexit` será removida. Comparações de igualdade (`==`) são usadas internamente durante o cancelamento do registro, portanto, as referências de função não precisam ter identidades correspondentes.

Ver também

Módulo `readline`

  Exemplo útil de `atexit` para ler e escrever arquivos de histórico de `readline`.

## Exemplo do `atexit`

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.