Сообщить об ошибке.

Класс finalize() модуля weakref в Python

Вызываемая функция при удалении объекта сборщиком мусора

Синтаксис:

import weakref

weakref.finalize(obj, func, *args, **kwargs)

Параметры:

  • obj - объект, для которого это все делается,
  • func - функция обратного вызова,
  • *args, **kwargs - аргументы функции func.

Возвращаемое значение:

Описание:

Класс finalize() модуля weakref возвращает вызываемый объект finalize, который будет вызываться при сборке мусора. В отличие от обычной слабой ссылки, finalize всегда будет существовать до тех пор, пока изначальный объект obj не будет удален сборщиком мусора, что значительно упрощает управление жизненным циклом.

Объект finalize считается живым до тех пор, пока он не будет вызван явно или при сборке мусора, а после этого он умрет. Вызов живого finalize возвращает результат func(*arg, **kwargs), тогда как вызов мертвого объекта finalize возвращает None.

Исключения, вызванные обратными вызовами finalize во время сборки мусора, будут показаны в стандартном выводе ошибок, но не будут распространяться. Они обрабатываются так же, как исключения, вызванные методом объекта __del__() или обратным вызовом слабой ссылки.

Когда программа завершает работу, вызывается каждый оставшийся живой объект finalize, если для его атрибута final.atexit не установлено значение False. Они вызываются в порядке, обратном создания.

Объект finalize никогда не вызовет func во время более поздней части выключения интерпретатора 1, когда глобальные переменные модуля могут быть заменены на None.

Примечание. Важно убедиться, что у func, args и kwargs нет прямых или косвенных ссылок на obj, поскольку в противном случае obj никогда не будет удален при сборке мусора. В частности, func не должна быть связанным методом obj.


Атрибуты и методы объекта finalize.

final.__call__():

Если self жив, то метод final.__call__() помечает его как удаленный и возвращает результат вызова func(*args, **kwargs). Если self удален, то возвращает None.

final.detach():

Если self жив, то метод final.detach() помечает его как удаленный и возвращает кортеж (obj, func, args, kwargs). Если self удален, то возвращает None.

final.peek():

Если self жив, то метод final.peek() возвращает кортеж (obj, func, args, kwargs). Если self удален, то возвращает None.

final.alive:

Атрибут final.alive который имеет значение True, если finalize жив, в противном случае - значение False.

final.atexit:

Атрибут final.atexit представляет собой логическое свойство доступное для записи, которое по умолчанию имеет значение True.

Когда программа закрывается, она вызывает все оставшиеся живые finalize, для которых atexit имеет значение True. Они вызываются в порядке, обратном создания.


Пример регистрации обратного вызова при выходе из программы.

Основное преимущество использования finalize заключается в том, что он упрощает регистрацию обратного вызова без необходимости сохранять возвращенный объект.

>>> import weakref
>>> class Object:
...     pass
...
>>> kenny = Object()
>>> weakref.finalize(kenny, print, "You killed Kenny!")  
# <finalize object at ...; for 'Object' at ...>
>>> del kenny
# You killed Kenny!

Объект finalize также может быть вызван напрямую. Однако finalize вызовет обратный вызов не более одного раза.

>>> import weakref
>>> def callback(x, y, z):
...     print("CALLBACK")
...     return x + y + z
... 
>>> obj = Object()
>>> f = weakref.finalize(obj, callback, 1, 2, z=3)
>>> assert f.alive
>>> assert f() == 6
# CALLBACK
>>> assert not f.alive
# Обратный вызов не вызван, 
# потому что finalize мертв
>>> f()
>>> del obj

Можно отменить регистрацию finalize, используя его метод final.detach(). Это удалит финализатор и возвратит аргументы, переданные конструктору при его создании.

>>> obj = Object()
>>> f = weakref.finalize(obj, callback, 1, 2, z=3)
>>> f.detach()                                           
# (<...Object object ...>, <function callback ...>, (1, 2), {'z': 3})
>>> newobj, func, args, kwargs = _
>>> assert not f.alive
>>> assert newobj is obj
>>> assert func(*args, **kwargs) == 6
# CALLBACK

Если для атрибута final.atexit не установлено значение False, то при завершении работы программы будет вызываться финализатор, если он еще жив.

>>> obj = Object()
>>> weakref.finalize(obj, print, "obj dead or exiting")
# <finalize object at ...; for 'Object' at ...>
>>> exit()
# obj dead or exiting

Ссылки по тексту:

1. Выключение интерпретатора: при завершении работы интерпретатор Python входит в особую фазу, где он постепенно освобождает все выделенные ресурсы, такие как модули и различные критические внутренние структуры. Он также делает несколько вызовов сборщику мусора. Это может инициировать выполнение кода в пользовательских деструкторах или слабых обратных вызовах. Код, выполняемый на этапе завершения работы, может сталкиваться с различными исключениями, поскольку ресурсы, на которые он опирается, могут больше не работать.