__del__es un finalizador . Se llama cuando un objeto se recolecta como basura, lo que ocurre en algún momento después de que se hayan eliminado todas las referencias al objeto.
En un caso simple, esto podría ser justo después de decir del xo, si xes una variable local, después de que finalice la función. En particular, a menos que haya referencias circulares, CPython (la implementación estándar de Python) recolectará basura inmediatamente.
Sin embargo, este es un detalle de implementación de CPython. La única propiedad requerida de la recolección de basura de Python es que ocurre después de que se han eliminado todas las referencias, por lo que es posible que esto no suceda inmediatamente después y que no suceda en absoluto .
Aún más, las variables pueden vivir durante mucho tiempo por muchas razones , por ejemplo, una excepción que se propaga o la introspección del módulo pueden mantener el recuento de referencias de variables mayor que 0. Además, la variable puede ser parte del ciclo de referencias : CPython con la recolección de basura activada se interrumpe más , pero no todos, esos ciclos, e incluso entonces solo periódicamente.
Dado que no tiene garantía de que se ejecute, nunca se debe poner el código con el que debe ejecutarse; en __del__()cambio, este código pertenece a la finallycláusula del trybloque oa un administrador de contexto en una withdeclaración. Sin embargo, hay casos de uso válidos para __del__: por ejemplo, si un objeto hace Xreferencia Yy también mantiene una copia de la Yreferencia en un global cache( cache['X -> Y'] = Y), sería de buena educación X.__del__eliminar también la entrada de la caché.
Si usted sabe que el destructor proporciona (en violación de la directriz anterior) una limpieza necesaria, es posible que desee llamar directamente , ya que no hay nada especial en él como un método: x.__del__(). Obviamente, debe hacerlo solo si sabe que no le importa que lo llamen dos veces. O, como último recurso, puede redefinir este método utilizando
type(x).__del__ = my_safe_cleanup_method