__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