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

gcsupport.md

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

1> **Источник:** https://python-all.ru/3.0/c-api/gcsupport.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Поддержка циклической сборки мусора89Для поддержки обнаружения и сбора мусора, связанного с циклическими ссылками, Python требует поддержки от типов объектов, которые являются «контейнерами» для других объектов (которые также могут быть контейнерами). Типы, не хранящие ссылок на другие объекты или хранящие ссылки только на атомарные типы (например, числа или строки), не нуждаются в явной поддержке сборки мусора.1011Чтобы создать контейнерный тип, поле [`tp_flags`](https://python-all.ru/3.0/c-api/typeobj.html#tp_flags) объекта типа должно содержать флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC), а также нужно предоставить реализацию обработчика [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse). Если экземпляры типа изменяемы, необходимо также реализовать [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear).1213#### `Py_TPFLAGS_HAVE_GC`1415Объекты с типом, у которого установлен этот флаг, должны соответствовать описанным здесь правилам. Для удобства такие объекты будут называться контейнерными объектами.1617Конструкторы контейнерных типов должны соответствовать двум правилам:18191. Память для объекта должна выделяться с помощью [`PyObject_GC_New`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_New) или `PyObject_GC_VarNew`.202. После инициализации всех полей, которые могут содержать ссылки на другие контейнеры, необходимо вызвать [`PyObject_GC_Track`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_Track).2122**\[PyObject\_GC\_New\]TYPE\* `PyObject_GC_New`(TYPE, [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject) *\*type*)**2324Аналог2526[`PyObject_New`](https://python-all.ru/3.0/c-api/allocation.html#PyObject_New)2728, но для контейнерных объектов с установленным флагом2930[`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC)3132.3334**\[PyObject\_GC\_NewVar\]TYPE\* `PyObject_GC_NewVar`(TYPE, [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject) *\*type*, Py\_ssize\_t *size*)**3536Аналог3738[`PyObject_NewVar`](https://python-all.ru/3.0/c-api/allocation.html#PyObject_NewVar)3940, но для контейнерных объектов с установленным флагом4142[`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC)4344.4546**\[PyObject\_GC\_Resize\][PyVarObject](https://python-all.ru/3.0/c-api/structures.html#PyVarObject) \* `PyObject_GC_Resize`([PyVarObject](https://python-all.ru/3.0/c-api/structures.html#PyVarObject) *\*op*, Py\_ssize\_t)**4748Изменяет размер объекта, выделенного с помощью4950[`PyObject_NewVar`](https://python-all.ru/3.0/c-api/allocation.html#PyObject_NewVar)5152. Возвращает объект нового размера или5354*NULL*5556в случае ошибки.5758**\[PyObject\_GC\_Track\]void `PyObject_GC_Track`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*op*)**5960Добавляет объект6162*op*6364в набор контейнерных объектов, отслеживаемых сборщиком. Сборщик может запускаться в неожиданные моменты, поэтому объекты должны быть корректными на время отслеживания. Этот вызов следует выполнить, когда все поля, обрабатываемые обработчиком6566[`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse)6768, станут корректными, обычно ближе к концу конструктора.6970**\[\_PyObject\_GC\_TRACK\]void `_PyObject_GC_TRACK`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*op*)**7172Макроверсия7374[`PyObject_GC_Track`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_Track)7576. Не предназначена для использования в модулях расширения.7778Аналогично, деаллокатор объекта должен соответствовать такой же паре правил:79801. Перед тем, как поля, ссылающиеся на другие контейнеры, станут недействительными, необходимо вызвать [`PyObject_GC_UnTrack`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_UnTrack).812. Память объекта должна освобождаться с помощью [`PyObject_GC_Del`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_Del).8283**\[PyObject\_GC\_Del\]void `PyObject_GC_Del`(void *\*op*)**8485Освобождает память, выделенную для объекта с помощью8687[`PyObject_GC_New`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_New)8889или9091[`PyObject_GC_NewVar`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_NewVar)9293.9495**\[PyObject\_GC\_UnTrack\]void `PyObject_GC_UnTrack`(void *\*op*)**9697Удаляет объект9899*op*100101из набора контейнерных объектов, отслеживаемых сборщиком. Обратите внимание, что для этого объекта можно снова вызвать102103[`PyObject_GC_Track`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_Track)104105, чтобы вернуть его в набор отслеживаемых объектов. Деаллокатор (обработчик106107[`tp_dealloc`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dealloc)108109) должен вызвать это для объекта до того, как любое из полей, используемых обработчиком110111[`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse)112113, станет недействительным.114115**\[\_PyObject\_GC\_UNTRACK\]void `_PyObject_GC_UNTRACK`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*op*)**116117Макроверсия118119[`PyObject_GC_UnTrack`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_UnTrack)120121. Не предназначена для использования в модулях расширения.122123Обработчик [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) принимает параметр-функцию следующего типа:124125**\[visitproc\]int `(*visitproc)`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*object*, void *\*arg*)**126127Тип функции посетителя, передаваемой обработчику128129[`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse)130131. Функция должна вызываться с объектом для обхода в качестве132133*object*134135и третьим параметром обработчика136137[`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse)138139в качестве140141*arg*142143. Ядро Python использует несколько функций посетителей для реализации обнаружения циклического мусора; не ожидается, что пользователям потребуется писать собственные функции посетителей.144145Обработчик [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) должен иметь следующий тип:146147**\[traverseproc\]int `(*traverseproc)`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*self*, [visitproc](https://python-all.ru/3.0/c-api/gcsupport.html#visitproc) *visit*, void *\*arg*)**148149Функция обхода для контейнерного объекта. Реализации должны вызывать функцию150151*visit*152153для каждого объекта, напрямую содержащегося в154155*self*156157, с параметрами для158159*visit*160161: содержащимся объектом и значением162163*arg*164165, переданным обработчику. Функция166167*visit*168169не должна вызываться с аргументом170171*NULL*172173в качестве объекта. Если174175*visit*176177возвращает ненулевое значение, его следует немедленно вернуть.178179Для упрощения написания обработчиков [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) предоставляется макрос [`Py_VISIT`](https://python-all.ru/3.0/c-api/gcsupport.html#Py_VISIT). Чтобы использовать этот макрос, реализация [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) должна называть свои аргументы именно *visit* и *arg*:180181**\[Py\_VISIT\]void `Py_VISIT`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*o*)**182183Вызывает колбэк *visit* с аргументами *o* и *arg*. Если *visit* возвращает ненулевое значение, вернуть его. Используя этот макрос, обработчики [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) выглядят так:184185```c186static int187my_traverse(Noddy *self, visitproc visit, void *arg)188{189    Py_VISIT(self->foo);190    Py_VISIT(self->bar);191    return 0;192}193```194195The [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear) handler must be of the [`inquiry`](https://python-all.ru/3.0/c-api/gcsupport.html#inquiry) type, or *NULL* if the object is immutable.196197**\[inquiry\]int `(*inquiry)`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*self*)**198199Удаляет ссылки, которые могли создать циклические ссылки. Неизменяемые объекты могут не определять этот метод, так как они никогда не могут напрямую создавать циклические ссылки. Обратите внимание, что объект после вызова этого метода всё ещё должен оставаться корректным (не следует просто вызывать200201[`Py_DECREF`](https://python-all.ru/3.0/c-api/refcounting.html#Py_DECREF)202203для ссылки). Сборщик вызовет этот метод, если обнаружит, что этот объект участвует в циклической ссылке.204