Документация Python неофициальный перевод

weakref.md

432 строк · 36.1 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.16/library/weakref.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `weakref` – Слабые ссылки89**Исходный код:** [Lib/weakref.py](https://python-all.ru/src/main/Lib/weakref.py)1011---1213Модуль `weakref` позволяет программисту Python создавать *слабые ссылки* на объекты.1415В дальнейшем под термином *referent* понимается объект, на который указывает слабая ссылка.1617Слабой ссылки на объект недостаточно, чтобы сохранить объект живым: когда единственные оставшиеся ссылки на референт являются слабыми ссылками, [сборщик мусора](https://python-all.ru/3.16/glossary.html#term-garbage-collection) может уничтожить референт и использовать его память для других целей. Однако, пока объект фактически не уничтожен, слабая ссылка может вернуть объект, даже если на него нет сильных ссылок.1819Основное применение слабых ссылок – реализация кэшей или отображений, содержащих большие объекты, когда требуется, чтобы большой объект не оставался в живых только потому, что он присутствует в кэше или отображении.2021Например, если у вас есть несколько больших бинарных объектов-изображений, вы можете захотеть связать имя с каждым. Если вы используете словарь Python для отображения имён на изображения или изображений на имена, объекты-изображения будут оставаться живыми только потому, что они присутствуют как значения или ключи в словарях. Классы [`WeakKeyDictionary`](https://python-all.ru/3.16/library/weakref.html#weakref.WeakKeyDictionary) и [`WeakValueDictionary`](https://python-all.ru/3.16/library/weakref.html#weakref.WeakValueDictionary), предоставляемые модулем `weakref`, являются альтернативой: они используют слабые ссылки для построения отображений, которые не сохраняют объекты живыми только из-за их присутствия в объектах-отображениях. Если, например, объект-изображение является значением в `WeakValueDictionary`, то, когда последние оставшиеся ссылки на этот объект-изображение являются слабыми ссылками, хранящимися в слабых отображениях, сборщик мусора может переработать объект, и соответствующие записи в слабых отображениях просто удаляются.2223[`WeakKeyDictionary`](https://python-all.ru/3.16/library/weakref.html#weakref.WeakKeyDictionary) и [`WeakValueDictionary`](https://python-all.ru/3.16/library/weakref.html#weakref.WeakValueDictionary) используют слабые ссылки в своей реализации, устанавливая функции обратного вызова на слабые ссылки, которые уведомляют слабые словари, когда ключ или значение были переработаны сборщиком мусора. [`WeakSet`](https://python-all.ru/3.16/library/weakref.html#weakref.WeakSet) реализует интерфейс [`set`](https://python-all.ru/3.16/library/stdtypes.html#set), но хранит слабые ссылки на свои элементы, подобно тому, как это делает `WeakKeyDictionary`.2425[`finalize`](https://python-all.ru/3.16/library/weakref.html#weakref.finalize) предоставляет простой способ зарегистрировать функцию очистки, которая будет вызвана, когда объект будет собран сборщиком мусора. Это проще в использовании, чем установка функции обратного вызова на необработанную слабую ссылку, поскольку модуль автоматически гарантирует, что финализатор остаётся живым до тех пор, пока объект не будет собран.2627Большинству программ должно быть достаточно использования одного из этих типов слабых контейнеров или [`finalize`](https://python-all.ru/3.16/library/weakref.html#weakref.finalize) – обычно нет необходимости создавать собственные слабые ссылки напрямую. Низкоуровневые механизмы предоставляются модулем `weakref` для продвинутого использования.2829Не все объекты могут быть слабо ссылаемыми. Объекты, поддерживающие слабые ссылки, включают экземпляры классов, функции, написанные на Python (но не на C), методы экземпляров, множества, неизменяемые множества, некоторые [файловые объекты](https://python-all.ru/3.16/glossary.html#term-file-object), [генераторы](https://python-all.ru/3.16/glossary.html#term-generator), объекты типов, сокеты, массивы, двусторонние очереди, объекты шаблонов регулярных выражений и объекты кода.3031Изменено в версии 3.2: Добавлена поддержка thread.lock, threading.Lock и объектов кода.3233Некоторые встроенные типы, такие как [`list`](https://python-all.ru/3.16/library/stdtypes.html#list) и [`dict`](https://python-all.ru/3.16/library/stdtypes.html#dict), не поддерживают напрямую слабые ссылки, но могут добавить поддержку через наследование:3435```python36class Dict(dict):37    pass3839obj = Dict(red=1, green=2, blue=3)   # этот объект поддерживает слабые ссылки40```4142**Особенность реализации CPython:** Другие встроенные типы, такие как [`tuple`](https://python-all.ru/3.16/library/stdtypes.html#tuple) и [`int`](https://python-all.ru/3.16/library/functions.html#int), не поддерживают слабые ссылки даже при наследовании.4344Расширяемые типы можно легко научить поддерживать слабые ссылки; см. [Поддержка слабых ссылок](https://python-all.ru/3.16/extending/newtypes.html#weakref-support).4546Когда для данного типа определены `__slots__`, поддержка слабых ссылок отключается, если в последовательности строк в объявлении `__slots__` также не присутствует строка `'__weakref__'`. Подробнее см. [документацию \_\_slots\_\_](https://python-all.ru/3.16/reference/datamodel.html#slots).4748#### `class weakref.ref(object[, callback])`4950Возвращает слабую ссылку на *object*. Исходный объект можно получить, вызвав объект ссылки, если референт ещё жив; если референт больше не жив, вызов объекта ссылки приведёт к возврату [`None`](https://python-all.ru/3.16/library/constants.html#None). Если *колбэк* указан и не равен `None`, и возвращённый объект weakref всё ещё жив, колбэк будет вызван, когда объект будет близок к финализации; объект слабой ссылки будет передан как единственный параметр колбэку; референт больше не будет доступен.5152Допускается создание нескольких слабых ссылок на один и тот же объект. Колбэки, зарегистрированные для каждой слабой ссылки, будут вызываться от самого недавно зарегистрированного колбэка до самого старого.5354Исключения, возбуждаемые колбэком, будут отмечены в стандартном потоке ошибок, но не могут быть распространены; они обрабатываются точно так же, как исключения, возбуждаемые методом [`__del__()`](https://python-all.ru/3.16/reference/datamodel.html#object.__del__) объекта.5556Слабые ссылки являются [хешируемыми](https://python-all.ru/3.16/glossary.html#term-hashable), если *object* хешируем. Они сохраняют своё хеш-значение даже после удаления *object*. Если [`hash()`](https://python-all.ru/3.16/library/functions.html#hash) вызывается впервые только после удаления *object*, вызов возбудит [`TypeError`](https://python-all.ru/3.16/library/exceptions.html#TypeError).5758Слабые ссылки поддерживают проверку на равенство, но не на упорядочивание. Если референты ещё живы, две ссылки имеют то же отношение равенства, что и их референты (независимо от *колбэк*). Если любой из референтов был удалён, ссылки равны только в том случае, если объекты ссылок являются одним и тем же объектом.5960Это тип, который можно наследовать, а не фабричная функция.6162Слабые ссылки являются [обобщёнными](https://python-all.ru/3.16/library/typing.html#generics) по типу объекта, на который они ссылаются.6364#### `__callback__`6566Этот атрибут только для чтения возвращает колбэк, в данный момент связанный с weakref. Если колбэка нет или референт weakref больше не жив, то этот атрибут будет иметь значение `None`.6768Изменено в версии 3.4: Добавлен атрибут [`__callback__`](https://python-all.ru/3.16/library/weakref.html#weakref.ref.__callback__).6970Изменено в версии 3.16.0a0 (не выпущена): вызывает `TypeError`, если *колбэк* не является вызываемым или `None`.7172#### `weakref.proxy(object[, callback])`7374Возвращает прокси на *object*, который использует слабую ссылку. Это позволяет использовать прокси в большинстве контекстов без необходимости явного разыменования, используемого с объектами слабых ссылок. Возвращаемый объект будет иметь тип либо `ProxyType`, либо `CallableProxyType`, в зависимости от того, является ли *object* вызываемым. Прокси-объекты не являются [хешируемыми](https://python-all.ru/3.16/glossary.html#term-hashable) независимо от референта; это избегает ряда проблем, связанных с их принципиально изменчивой природой, и предотвращает их использование в качестве ключей словаря. *колбэк* – это то же самое, что параметр с тем же именем у функции [`ref()`](https://python-all.ru/3.16/library/weakref.html#weakref.ref).7576Доступ к атрибуту прокси-объекта после того, как референт был собран сборщиком мусора, возбуждает [`ReferenceError`](https://python-all.ru/3.16/library/exceptions.html#ReferenceError).7778Изменено в версии 3.8: Расширена поддержка операторов для прокси-объектов, включены операторы матричного умножения `@` и `@=`.7980Изменено в версии 3.16.0a0 (не выпущена): вызывает `TypeError`, если *колбэк* не является вызываемым или `None`.8182#### `weakref.getweakrefcount(object)`8384Возвращает количество слабых ссылок и прокси, которые ссылаются на *object*.8586#### `weakref.getweakrefs(object)`8788Возвращает список всех объектов слабых ссылок и прокси, которые ссылаются на *object*.8990#### `class weakref.WeakKeyDictionary([dict])`9192Класс отображения, который хранит слабые ссылки на ключи. Записи словаря будут удалены, когда на ключ больше не останется сильных ссылок. Это можно использовать для связывания дополнительных данных с объектом, принадлежащим другим частям приложения, без добавления атрибутов к этим объектам. Это особенно полезно для объектов, которые переопределяют доступ к атрибутам.9394Обратите внимание, что когда в словарь вставляется ключ, равный по значению существующему ключу (но не совпадающий по идентичности), он заменяет значение, но не заменяет существующий ключ. Из-за этого, когда удаляется ссылка на исходный ключ, также удаляется и запись в словаре:9596```python97>>> class T(str): pass98...99>>> k1, k2 = T(), T()100>>> d = weakref.WeakKeyDictionary()101>>> d[k1] = 1   # d = {k1: 1}102>>> d[k2] = 2   # d = {k1: 2}103>>> del k1      # d = {}104```105106Обходной путь – удалить ключ перед переназначением:107108```python109>>> class T(str): pass110...111>>> k1, k2 = T(), T()112>>> d = weakref.WeakKeyDictionary()113>>> d[k1] = 1   # d = {k1: 1}114>>> del d[k1]115>>> d[k2] = 2   # d = {k2: 2}116>>> del k1      # d = {k2: 2}117```118119Изменено в версии 3.9: Добавлена поддержка операторов `|` и `|=`, как указано в [**PEP 584**](https://python-all.ru/3.16/library/weakref.html).120121[`WeakKeyDictionary`](https://python-all.ru/3.16/library/weakref.html#weakref.WeakKeyDictionary) объекты имеют дополнительный метод, который напрямую раскрывает внутренние ссылки. Эти ссылки не гарантированно являются «живыми» на момент использования, поэтому результат вызова ссылок необходимо проверять перед использованием. Это можно использовать, чтобы избежать создания ссылок, которые заставят сборщик мусора удерживать ключи дольше, чем необходимо.122123#### `WeakKeyDictionary.keyrefs()`124125Возвращает итератор по слабым ссылкам на ключи.126127#### `class weakref.WeakValueDictionary([dict])`128129Класс отображения, который хранит слабые ссылки на значения. Записи словаря будут удалены, когда на значение больше не будет сильных ссылок.130131Изменено в версии 3.9: Добавлена поддержка операторов `|` и `|=`, как указано в [**PEP 584**](https://python-all.ru/3.16/library/weakref.html).132133[`WeakValueDictionary`](https://python-all.ru/3.16/library/weakref.html#weakref.WeakValueDictionary) объекты имеют дополнительный метод, который имеет те же проблемы, что и метод [`WeakKeyDictionary.keyrefs()`](https://python-all.ru/3.16/library/weakref.html#weakref.WeakKeyDictionary.keyrefs).134135#### `WeakValueDictionary.valuerefs()`136137Возвращает итератор по слабым ссылкам на значения.138139#### `class weakref.WeakSet([elements])`140141Класс множества, который хранит слабые ссылки на свои элементы. Элемент будет удален, когда на него больше не останется сильных ссылок.142143#### `class weakref.WeakMethod(method[, callback])`144145Пользовательский подкласс [`ref`](https://python-all.ru/3.16/library/weakref.html#weakref.ref), который имитирует слабую ссылку на привязанный метод (т.е. метод, определенный в классе и полученный через экземпляр). Поскольку привязанный метод является эфемерным, обычная слабая ссылка не может его удержать. `WeakMethod` содержит специальный код для воссоздания привязанного метода до тех пор, пока не будут удалены объект или исходная функция:146147```python148>>> class C:149...     def method(self):150...         print("method called!")151...152>>> c = C()153>>> r = weakref.ref(c.method)154>>> r()155>>> r = weakref.WeakMethod(c.method)156>>> r()157<bound method C.method of <__main__.C object at 0x7fc859830220>>158>>> r()()159method called!160>>> del c161>>> gc.collect()1620163>>> r()164>>>165```166167*колбэк* – это то же самое, что и одноименный параметр функции [`ref()`](https://python-all.ru/3.16/library/weakref.html#weakref.ref).168169Добавлено в версии 3.4.170171#### `class weakref.finalize(obj, func, /, *args, **kwargs)`172173Возвращает вызываемый объект финализатора, который будет вызван, когда *obj* будет собран сборщиком мусора. В отличие от обычной слабой ссылки, финализатор всегда будет существовать до тех пор, пока не будет собран сам объект ссылки, что значительно упрощает управление жизненным циклом.174175Финализатор считается *живым*, пока он не вызван (явно или при сборке мусора), после чего он считается *мертвым*. Вызов живого финализатора возвращает результат вычисления `func(*arg, **kwargs)`, а вызов мертвого финализатора возвращает [`None`](https://python-all.ru/3.16/library/constants.html#None).176177Исключения, возбуждаемые колбэками финализатора во время сборки мусора, будут показаны в стандартный поток ошибок, но не могут быть распространены. Они обрабатываются так же, как исключения, возбуждаемые методом [`__del__()`](https://python-all.ru/3.16/reference/datamodel.html#object.__del__) объекта или колбэком слабой ссылки.178179При завершении программы вызывается каждый оставшийся живой финализатор, если только его атрибут [`atexit`](https://python-all.ru/3.16/library/atexit.html#module-atexit) не установлен в false. Они вызываются в порядке, обратном порядку создания.180181Финализатор никогда не вызовет свой колбэк на позднем этапе [завершения интерпретатора](https://python-all.ru/3.16/glossary.html#term-interpreter-shutdown), когда глобальные переменные модуля могут быть заменены на [`None`](https://python-all.ru/3.16/library/constants.html#None).182183#### `__call__()`184185Если *self* жив, то пометить его как мертвый и вернуть результат вызова `func(*args, **kwargs)`. Если *self* мертв, то вернуть [`None`](https://python-all.ru/3.16/library/constants.html#None).186187#### `detach()`188189Если *self* жив, то пометить его как мёртвый и вернуть кортеж `(obj, func, args, kwargs)`. Если *self* мёртв, то вернуть [`None`](https://python-all.ru/3.16/library/constants.html#None).190191#### `peek()`192193Если *self* жив, то вернуть кортеж `(obj, func, args, kwargs)`. Если *self* мёртв, то вернуть [`None`](https://python-all.ru/3.16/library/constants.html#None).194195#### `alive`196197Свойство, которое истинно, если финализатор жив, и ложно в противном случае.198199#### `atexit`200201Записываемое логическое свойство, по умолчанию истинное. При завершении программы вызываются все оставшиеся живые финализаторы, для которых [`atexit`](https://python-all.ru/3.16/library/weakref.html#weakref.finalize.atexit) истинно. Они вызываются в порядке, обратном порядку создания.202203> **Примечание**204>205> Важно убедиться, что *func*, *args* и *kwargs* не содержат ссылок на *obj*, ни прямых, ни косвенных, иначе *obj* никогда не будет собран сборщиком мусора. В частности, *func* не должен быть привязанным методом *obj*.206207Добавлено в версии 3.4.208209#### `class weakref.ReferenceType`210211Объект типа для объектов слабых ссылок.212213#### `class weakref.ProxyType`214215Объект типа для прокси-объектов, которые не являются вызываемыми.216217#### `class weakref.CallableProxyType`218219Объект типа для прокси вызываемых объектов.220221#### `weakref.ProxyTypes`222223Последовательность, содержащая все объекты типа для прокси. Это упрощает проверку, является ли объект прокси, без необходимости называть оба типа прокси.224225> **См. также**226>227> **[**PEP 205**](https://python-all.ru/3.16/library/weakref.html) – слабые ссылки**228>229> Предложение и обоснование этой возможности, включая ссылки на более ранние реализации и информацию о подобных возможностях в других языках.230231## Объекты слабых ссылок232233Объекты слабых ссылок не имеют методов и атрибутов, кроме [`ref.__callback__`](https://python-all.ru/3.16/library/weakref.html#weakref.ref.__callback__). Объект слабой ссылки позволяет получить объект ссылки (referent), если он ещё существует, путём вызова:234235```python236>>> import weakref237>>> class Object:238...     pass239...240>>> o = Object()241>>> r = weakref.ref(o)242>>> o2 = r()243>>> o is o2244True245```246247Если объект ссылки больше не существует, вызов объекта ссылки возвращает [`None`](https://python-all.ru/3.16/library/constants.html#None):248249```python250>>> del o, o2251>>> print(r())252None253```254255Проверка того, что объект слабой ссылки всё ещё жив, должна выполняться с помощью выражения `ref() is not None`. Обычно код приложения, которому нужно использовать объект ссылки, должен следовать следующему шаблону:256257```python258# r – объект слабой ссылки259o = r()260if o is None:261    # объект был собран сборщиком мусора262    print("Object has been deallocated; can't frobnicate.")263else:264    print("Object is still live!")265    o.do_something_useful()266```267268Использование отдельной проверки «живучести» создаёт состояния гонки в многопоточных приложениях; другой поток может привести к инвалидации слабой ссылки до того, как она будет вызвана; идиома, показанная выше, безопасна как в многопоточных, так и в однопоточных приложениях.269270Специализированные версии объектов [`ref`](https://python-all.ru/3.16/library/weakref.html#weakref.ref) можно создавать через наследование. Это используется в реализации [`WeakValueDictionary`](https://python-all.ru/3.16/library/weakref.html#weakref.WeakValueDictionary) для уменьшения накладных расходов памяти на каждую запись в отображении. Это может быть особенно полезно для связывания дополнительной информации со ссылкой, но также может использоваться для добавления дополнительной обработки при вызовах для получения объекта ссылки.271272Этот пример показывает, как подкласс [`ref`](https://python-all.ru/3.16/library/weakref.html#weakref.ref) можно использовать для хранения дополнительной информации об объекте и влиять на значение, возвращаемое при обращении к объекту ссылки:273274```python275import weakref276277class ExtendedRef(weakref.ref):278    def __init__(self, ob, callback=None, /, **annotations):279        super().__init__(ob, callback)280        self.__counter = 0281        for k, v in annotations.items():282            setattr(self, k, v)283284    def __call__(self):285        """Возвращает пару, содержащую объект и количество286        вызовов ссылки.287        """288        ob = super().__call__()289        if ob is not None:290            self.__counter += 1291            ob = (ob, self.__counter)292        return ob293```294295## Пример296297Этот простой пример показывает, как приложение может использовать идентификаторы объектов для получения объектов, которые оно уже видело. Идентификаторы объектов затем можно использовать в других структурах данных, не заставляя объекты оставаться живыми, но объекты всё ещё можно получить по идентификатору, если они живы.298299```python300import weakref301302_id2obj_dict = weakref.WeakValueDictionary()303304def remember(obj):305    oid = id(obj)306    _id2obj_dict[oid] = obj307    return oid308309def id2obj(oid):310    return _id2obj_dict[oid]311```312313## Объекты финализаторов314315Основное преимущество использования [`finalize`](https://python-all.ru/3.16/library/weakref.html#weakref.finalize) заключается в том, что оно упрощает регистрацию колбэка без необходимости сохранять возвращаемый объект финализатора. Например316317```python318>>> import weakref319>>> class Object:320...     pass321...322>>> kenny = Object()323>>> weakref.finalize(kenny, print, "You killed Kenny!")324<finalize object at ...; for 'Object' at ...>325>>> del kenny326You killed Kenny!327```328329Финализатор также можно вызывать напрямую. Однако финализатор вызовет колбэк не более одного раза.330331```python332>>> def callback(x, y, z):333...     print("CALLBACK")334...     return x + y + z335...336>>> obj = Object()337>>> f = weakref.finalize(obj, callback, 1, 2, z=3)338>>> assert f.alive339>>> assert f() == 6340CALLBACK341>>> assert not f.alive342>>> f()                     # колбэк не вызван, так как финализатор неактивен343>>> del obj                 # колбэк не вызван, так как финализатор неактивен344```345346Можно отменить регистрацию финализатора с помощью его метода [`detach()`](https://python-all.ru/3.16/library/weakref.html#weakref.finalize.detach). Это уничтожает финализатор и возвращает аргументы, переданные конструктору при его создании.347348```python349>>> obj = Object()350>>> f = weakref.finalize(obj, callback, 1, 2, z=3)351>>> f.detach()352(<...Object object ...>, <function callback ...>, (1, 2), {'z': 3})353>>> newobj, func, args, kwargs = _354>>> assert not f.alive355>>> assert newobj is obj356>>> assert func(*args, **kwargs) == 6357CALLBACK358```359360Если не установить атрибут [`atexit`](https://python-all.ru/3.16/library/weakref.html#weakref.finalize.atexit) в значение [`False`](https://python-all.ru/3.16/library/constants.html#False), финализатор будет вызван при завершении программы, если он всё ещё жив. Например361362```pycon363>>> obj = Object()364>>> weakref.finalize(obj, print, "obj dead or exiting")365<finalize object at ...; for 'Object' at ...>366>>> exit()367obj dead or exiting368```369370## Сравнение финализаторов с методами [`__del__()`](https://python-all.ru/3.16/reference/datamodel.html#object.__del__)371372Предположим, мы хотим создать класс, экземпляры которого представляют временные каталоги. Каталоги должны удаляться вместе с их содержимым при наступлении первого из следующих событий:373374- объект удаляется сборщиком мусора,375- вызывается метод `remove()` объекта, или376- программа завершается.377378Можно попробовать реализовать класс с помощью метода [`__del__()`](https://python-all.ru/3.16/reference/datamodel.html#object.__del__) следующим образом:379380```python381class TempDir:382    def __init__(self):383        self.name = tempfile.mkdtemp()384385    def remove(self):386        if self.name is not None:387            shutil.rmtree(self.name)388            self.name = None389390    @property391    def removed(self):392        return self.name is None393394    def __del__(self):395        self.remove()396```397398Начиная с Python 3.4, методы [`__del__()`](https://python-all.ru/3.16/reference/datamodel.html#object.__del__) больше не препятствуют сборке мусора циклических ссылок, и глобальные переменные модуля больше не принуждаются к [`None`](https://python-all.ru/3.16/library/constants.html#None) во время [завершения интерпретатора](https://python-all.ru/3.16/glossary.html#term-interpreter-shutdown). Поэтому этот код должен без проблем работать в CPython.399400Однако обработка методов [`__del__()`](https://python-all.ru/3.16/reference/datamodel.html#object.__del__), как известно, зависит от реализации, поскольку она опирается на внутренние детали реализации сборщика мусора интерпретатора.401402Более надёжная альтернатива – определить финализатор, который ссылается только на нужные ему функции и объекты, а не имеет доступ ко всему состоянию объекта:403404```python405class TempDir:406    def __init__(self):407        self.name = tempfile.mkdtemp()408        self._finalizer = weakref.finalize(self, shutil.rmtree, self.name)409410    def remove(self):411        self._finalizer()412413    @property414    def removed(self):415        return not self._finalizer.alive416```417418Определённый таким образом, наш финализатор получает только ссылку на те детали, которые нужны для корректной очистки каталога. Если объект никогда не будет удалён сборщиком мусора, финализатор всё равно будет вызван при завершении программы.419420Ещё одно преимущество финализаторов на основе weakref в том, что их можно использовать для регистрации финализаторов у классов, определение которых контролируется сторонними разработчиками, например, для выполнения кода при выгрузке модуля:421422```python423import weakref, sys424def unloading_module():425    # неявная ссылка на глобальные переменные модуля из тела функции426weakref.finalize(sys.modules[__name__], unloading_module)427```428429> **Примечание**430>431> Если создать объект финализатора в фоновом потоке в момент завершения программы, то есть вероятность, что финализатор не будет вызван при выходе. Однако в фоновом потоке [`atexit.register()`](https://python-all.ru/3.16/library/atexit.html#atexit.register), `try: ... finally: ...` и `with: ...` также не гарантируют очистку.432