__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