__del__é um finalizador . É chamado quando um objeto é coletado como lixo, o que acontece em algum ponto depois que todas as referências ao objeto foram excluídas.
Em um caso simples, isso poderia ser logo após você dizer del xou, se xfor uma variável local, após o término da função. Em particular, a menos que haja referências circulares, o CPython (a implementação padrão do Python) fará a coleta de lixo imediatamente.
No entanto, este é um detalhe de implementação do CPython. A única propriedade necessária da coleta de lixo do Python é que ela acontece depois que todas as referências foram excluídas, então isso pode não acontecer necessariamente logo depois e pode nem acontecer .
Ainda mais, as variáveis podem viver por muito tempo por muitos motivos , por exemplo, uma exceção de propagação ou introspecção de módulo pode manter a contagem de referência de variável maior que 0. Além disso, a variável pode ser uma parte do ciclo de referências - CPython com coleta de lixo ativada quebras na maioria , mas não todos, esses ciclos, e mesmo assim, apenas periodicamente.
Já que você não tem garantia de que será executado, nunca se deve colocar o código que você precisa para ser executado __del__()- em vez disso, esse código pertence à finallycláusula do trybloco ou a um gerenciador de contexto em uma withinstrução. No entanto, existem casos de uso válidos para __del__: por exemplo, se um objeto faz Xreferência Ye também mantém uma cópia de Yreferência em um global cache( cache['X -> Y'] = Y), seria educado X.__del__também excluir a entrada do cache.
Se você sabe que o destruidor fornece (em violação da diretriz acima) a limpeza necessária, você pode querer chamá-lo diretamente , uma vez que não há nada de especial sobre ele como um método: x.__del__(). Obviamente, você só deve fazer isso se souber que não se importa em ser chamado duas vezes. Ou, como último recurso, você pode redefinir esse método usando
type(x).__del__ = my_safe_cleanup_method