__del__є фіналізатором . Він називається, коли об'єкт збирається сміттям, що відбувається в якийсь момент після видалення всіх посилань на об'єкт.
У простому випадку це може бути відразу після того, як ви скажете, del xабо, якщо xце локальна змінна, після закінчення функції. Зокрема, якщо немає кругових посилань, CPython (стандартна реалізація Python) негайно збиратиме сміття.
Однак, це деталізація реалізації CPython. Єдиною необхідною властивістю збору сміття Python є те, що це відбувається після видалення всіх посилань, тому це може не бути необхідним відразу після цього, а може і не статися взагалі. .
Навіть більше, змінні можуть тривалий час жити з багатьох причин , наприклад, розповсюджувальний виняток або інтроспекція модуля можуть підтримувати кількість змінних посилань більше 0. Також змінна може бути частиною циклу посилань - CPython із включеним збиранням сміття на перервах більшість , але не всі, такі цикли, та й то лише періодично.
Оскільки у вас немає гарантії, що вона виконується, ніколи не слід ставити код, який потрібно запустити __del__()- натомість цей код належить до finallyпункту tryблоку або до менеджера контексту у withвиписці. Однак є дійсні випадки використання для __del__: наприклад, якщо на Xпосилання на об'єкт посилається Yі зберігається копія Yпосилання в глобальному cache( cache['X -> Y'] = Y), то було б ввічливо X.__del__також видалити запис кешу.
Якщо ви знаєте , що деструкція забезпечує (в порушення зазначеного вище орієнтира) необхідної очищення, ви можете назвати це безпосередньо , так як немає нічого особливого, як метод: x.__del__(). Очевидно, ви повинні робити це лише в тому випадку, якщо знаєте, що не проти подзвонити двічі. Або, в крайньому випадку, ви можете переглянути цей метод за допомогою
type(x).__del__ = my_safe_cleanup_method