import weakref weakref.finalize(obj, func, *args, **kwargs)
obj
- объект, для которого это все делается,func
- функция обратного вызова,*args
, **kwargs
- аргументы функции func
.finalize
.Класс 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 входит в особую фазу, где он постепенно освобождает все выделенные ресурсы, такие как модули и различные критические внутренние структуры. Он также делает несколько вызовов сборщику мусора. Это может инициировать выполнение кода в пользовательских деструкторах или слабых обратных вызовах. Код, выполняемый на этапе завершения работы, может сталкиваться с различными исключениями, поскольку ресурсы, на которые он опирается, могут больше не работать.