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

gcsupport.md

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

1> **Источник:** https://python-all.ru/3.1/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.1/c-api/typeobj.html#tp_flags) объекта типа должно содержать флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.1/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC), а также нужно предоставить реализацию обработчика [`tp_traverse`](https://python-all.ru/3.1/c-api/typeobj.html#tp_traverse). Если экземпляры типа изменяемы, необходимо также реализовать [`tp_clear`](https://python-all.ru/3.1/c-api/typeobj.html#tp_clear).1213#### `Py_TPFLAGS_HAVE_GC`1415Объекты с типом, у которого установлен этот флаг, должны соответствовать правилам, описанным здесь. Для удобства такие объекты будут называться контейнерными объектами.1617Конструкторы контейнерных типов должны соответствовать двум правилам:18191. Память для объекта должна выделяться с помощью [`PyObject_GC_New()`](https://python-all.ru/3.1/c-api/gcsupport.html#PyObject_GC_New) или [`PyObject_GC_NewVar()`](https://python-all.ru/3.1/c-api/gcsupport.html#PyObject_GC_NewVar).202. Как только все поля, которые могут содержать ссылки на другие контейнеры, будут инициализированы, необходимо вызвать [`PyObject_GC_Track()`](https://python-all.ru/3.1/c-api/gcsupport.html#PyObject_GC_Track).2122**TYPE\* `PyObject_GC_New`(TYPE, [PyTypeObject](https://python-all.ru/3.1/c-api/type.html#PyTypeObject) *\*type*)**2324Аналог2526[`PyObject_New()`](https://python-all.ru/3.1/c-api/allocation.html#PyObject_New)2728, но для контейнерных объектов с установленным флагом2930[`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.1/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC)3132.3334**TYPE\* `PyObject_GC_NewVar`(TYPE, [PyTypeObject](https://python-all.ru/3.1/c-api/type.html#PyTypeObject) *\*type*, Py\_ssize\_t *size*)**3536Аналог3738[`PyObject_NewVar()`](https://python-all.ru/3.1/c-api/allocation.html#PyObject_NewVar)3940, но для контейнерных объектов с установленным флагом4142[`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.1/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC)4344.4546**TYPE\* `PyObject_GC_Resize`(TYPE, [PyVarObject](https://python-all.ru/3.1/c-api/structures.html#PyVarObject) *\*op*, Py\_ssize\_t *newsize*)**4748Изменяет размер объекта, выделенного функцией4950[`PyObject_NewVar()`](https://python-all.ru/3.1/c-api/allocation.html#PyObject_NewVar)5152. Возвращает объект нового размера или5354*NULL*5556в случае ошибки.5758**void `PyObject_GC_Track`([PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*op*)**5960Добавляет объект6162*op*6364в набор контейнерных объектов, отслеживаемых сборщиком. Сборщик может запускаться в неожиданные моменты, поэтому отслеживаемые объекты должны быть корректными. Этот вызов следует делать после того, как все поля, обрабатываемые обработчиком6566[`tp_traverse`](https://python-all.ru/3.1/c-api/typeobj.html#tp_traverse)6768, станут корректными, обычно ближе к концу конструктора.6970**void `_PyObject_GC_TRACK`([PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*op*)**7172Макроверсия7374[`PyObject_GC_Track()`](https://python-all.ru/3.1/c-api/gcsupport.html#PyObject_GC_Track)7576. Не предназначена для использования в модулях расширения.7778Аналогично, деаллокатор объекта должен соответствовать такой же паре правил:79801. Перед тем как поля, ссылающиеся на другие контейнеры, станут недействительными, необходимо вызвать [`PyObject_GC_UnTrack()`](https://python-all.ru/3.1/c-api/gcsupport.html#PyObject_GC_UnTrack).812. Память объекта должна освобождаться с помощью [`PyObject_GC_Del()`](https://python-all.ru/3.1/c-api/gcsupport.html#PyObject_GC_Del).8283**void `PyObject_GC_Del`(void *\*op*)**8485Освобождает память, выделенную для объекта с помощью8687[`PyObject_GC_New()`](https://python-all.ru/3.1/c-api/gcsupport.html#PyObject_GC_New)8889или9091[`PyObject_GC_NewVar()`](https://python-all.ru/3.1/c-api/gcsupport.html#PyObject_GC_NewVar)9293.9495**void `PyObject_GC_UnTrack`(void *\*op*)**9697Удаляет объект9899*op*100101из набора контейнерных объектов, отслеживаемых сборщиком. Обратите внимание, что102103[`PyObject_GC_Track()`](https://python-all.ru/3.1/c-api/gcsupport.html#PyObject_GC_Track)104105может быть вызвана снова для этого объекта, чтобы вернуть его в набор отслеживаемых. Деаллокатор (обработчик106107[`tp_dealloc`](https://python-all.ru/3.1/c-api/typeobj.html#tp_dealloc)108109) должен вызывать эту функцию для объекта до того, как какие-либо поля, используемые обработчиком110111[`tp_traverse`](https://python-all.ru/3.1/c-api/typeobj.html#tp_traverse)112113, станут недействительными.114115**void `_PyObject_GC_UNTRACK`([PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*op*)**116117Макроверсия118119[`PyObject_GC_UnTrack()`](https://python-all.ru/3.1/c-api/gcsupport.html#PyObject_GC_UnTrack)120121. Не предназначена для использования в модулях расширения.122123Обработчик [`tp_traverse`](https://python-all.ru/3.1/c-api/typeobj.html#tp_traverse) принимает параметр-функцию следующего типа:124125**int `(*visitproc)`([PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*object*, void *\*arg*)**126127Тип функции посещения, передаваемой обработчику128129[`tp_traverse`](https://python-all.ru/3.1/c-api/typeobj.html#tp_traverse)130131. Функцию следует вызывать с объектом для обхода в качестве132133*object*134135и третьим параметром обработчика136137[`tp_traverse`](https://python-all.ru/3.1/c-api/typeobj.html#tp_traverse)138139в качестве140141*arg*142143. Ядро Python использует несколько функций посещения для обнаружения циклического мусора; не предполагается, что пользователям понадобится писать собственные функции посещения.144145Обработчик [`tp_traverse`](https://python-all.ru/3.1/c-api/typeobj.html#tp_traverse) должен иметь следующий тип:146147**int `(*traverseproc)`([PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*self*, [visitproc](https://python-all.ru/3.1/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.1/c-api/typeobj.html#tp_traverse) предоставляется макрос [`Py_VISIT()`](https://python-all.ru/3.1/c-api/gcsupport.html#Py_VISIT). Чтобы использовать этот макрос, реализация [`tp_traverse`](https://python-all.ru/3.1/c-api/typeobj.html#tp_traverse) должна называть свои аргументы именно *visit* и *arg*:180181**void `Py_VISIT`([PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*o*)**182183Вызывает колбэк *visit* с аргументами *o* и *arg*. Если *visit* возвращает ненулевое значение, возвращает его. С использованием этого макроса обработчики [`tp_traverse`](https://python-all.ru/3.1/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```194195Обработчик [`tp_clear`](https://python-all.ru/3.1/c-api/typeobj.html#tp_clear) должен иметь тип [`inquiry`](https://python-all.ru/3.1/c-api/gcsupport.html#inquiry) или *NULL*, если объект неизменяем.196197**int `(*inquiry)`([PyObject](https://python-all.ru/3.1/c-api/structures.html#PyObject) *\*self*)**198199Удаляет ссылки, которые могли создать циклические ссылки. Неизменяемые объекты могут не определять этот метод, так как они никогда не могут напрямую создавать циклические ссылки. Обратите внимание, что объект после вызова этого метода всё ещё должен быть корректным (нельзя просто вызвать200201[`Py_DECREF()`](https://python-all.ru/3.1/c-api/refcounting.html#Py_DECREF)202203на ссылку). Сборщик вызовет этот метод, если обнаружит, что этот объект вовлечён в циклическую ссылку.204