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

gcsupport.md

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

1> **Источник:** https://python-all.ru/3.2/c-api/gcsupport.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Поддержка циклической сборки мусора89Поддержка Python обнаружения и сбора мусора, связанного с циклическими ссылками, требует поддержки со стороны объектных типов, которые являются «контейнерами» для других объектов, которые также могут быть контейнерами. Типы, которые не хранят ссылок на другие объекты или хранят только ссылки на атомарные типы (например, числа или строки), не нуждаются в явной поддержке сборки мусора.1011Чтобы создать тип-контейнер, поле `tp_flags` объекта типа должно включать [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) и предоставлять реализацию обработчика `tp_traverse`. Если экземпляры типа изменяемы, также необходимо предоставить реализацию `tp_clear`.1213#### `Py_TPFLAGS_HAVE_GC`1415Объекты с типом, у которого установлен этот флаг, должны соответствовать правилам, описанным здесь. Для удобства такие объекты будут называться контейнерными объектами.1617Конструкторы контейнерных типов должны соответствовать двум правилам:18191. Память для объекта должна выделяться с помощью [`PyObject_GC_New()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_New) или [`PyObject_GC_NewVar()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_NewVar).202. Как только все поля, которые могут содержать ссылки на другие контейнеры, будут инициализированы, необходимо вызвать [`PyObject_GC_Track()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_Track).2122#### `TYPE* PyObject_GC_New(TYPE, PyTypeObject *type)`2324Аналог [`PyObject_New()`](https://python-all.ru/3.2/c-api/allocation.html#PyObject_New), но для контейнерных объектов с установленным флагом [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).2526#### `TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size)`2728Аналог [`PyObject_NewVar()`](https://python-all.ru/3.2/c-api/allocation.html#PyObject_NewVar), но для контейнерных объектов с установленным флагом [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).2930#### `TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize)`3132Изменяет размер объекта, выделенного функцией [`PyObject_NewVar()`](https://python-all.ru/3.2/c-api/allocation.html#PyObject_NewVar). Возвращает объект нового размера или *NULL* в случае ошибки.3334#### `void PyObject_GC_Track(PyObject *op)`3536Добавляет объект *op* в набор объектов-контейнеров, отслеживаемых сборщиком. Сборщик может запускаться в непредвиденные моменты, поэтому объекты должны быть корректны во время отслеживания. Этот вызов следует производить, как только все поля, обрабатываемые обработчиком `tp_traverse`, станут корректными, обычно ближе к концу конструктора.3738#### `void _PyObject_GC_TRACK(PyObject *op)`3940Макроверсия [`PyObject_GC_Track()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_Track). Не предназначена для использования в модулях расширения.4142Аналогично, деаллокатор объекта должен соответствовать такой же паре правил:43441. Перед тем как поля, ссылающиеся на другие контейнеры, станут недействительными, необходимо вызвать [`PyObject_GC_UnTrack()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_UnTrack).452. Память объекта должна освобождаться с помощью [`PyObject_GC_Del()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_Del).4647#### `void PyObject_GC_Del(void *op)`4849Освобождает память, выделенную для объекта с помощью [`PyObject_GC_New()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_New) или [`PyObject_GC_NewVar()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_NewVar).5051#### `void PyObject_GC_UnTrack(void *op)`5253Удаляет объект *op* из набора объектов-контейнеров, отслеживаемых сборщиком. Обратите внимание: [`PyObject_GC_Track()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_Track) снова может быть вызвана для этого объекта, чтобы добавить его обратно в набор отслеживаемых. Деаллокатор (обработчик `tp_dealloc`) должен вызывать эту функцию для объекта до того, как какие-либо из полей, используемых обработчиком `tp_traverse`, станут некорректными.5455#### `void _PyObject_GC_UNTRACK(PyObject *op)`5657Макроверсия [`PyObject_GC_UnTrack()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_UnTrack). Не предназначена для использования в модулях расширения.5859Обработчик `tp_traverse` принимает параметр-функцию следующего типа:6061**int `(*visitproc)`([PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject) *\*object*, void *\*arg*)**6263Тип функции-посетителя, передаваемой обработчику `tp_traverse`. Функция должна вызываться с объектом для обхода в качестве *object* и третьим параметром обработчика `tp_traverse` в качестве *arg*. Ядро Python использует несколько функций-посетителей для реализации обнаружения циклического мусора; не предполагается, что пользователям потребуется писать собственные функции-посетители.6465Обработчик `tp_traverse` должен иметь следующий тип:6667**int `(*traverseproc)`([PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject) *\*self*, [visitproc](https://python-all.ru/3.2/c-api/gcsupport.html#visitproc) *visit*, void *\*arg*)**6869Функция обхода для контейнерного объекта. Реализации должны вызывать функцию *visit* для каждого объекта, непосредственно содержащегося в *self*, с параметрами *visit*: содержащийся объект и значение *arg*, переданное обработчику. Функция *visit* не должна вызываться с аргументом-объектом *NULL*. Если *visit* возвращает ненулевое значение, его следует немедленно вернуть.7071Для упрощения написания обработчиков `tp_traverse` предоставляется макрос [`Py_VISIT()`](https://python-all.ru/3.2/c-api/gcsupport.html#Py_VISIT). Чтобы использовать этот макрос, реализация `tp_traverse` должна называть свои аргументы именно *visit* и *arg*:7273#### `void Py_VISIT(PyObject *o)`7475Вызывает колбэк *visit* с аргументами *o* и *arg*. Если *visit* возвращает ненулевое значение, верните его. С использованием этого макроса обработчики `tp_traverse` выглядят так:7677```c78static int79my_traverse(Noddy *self, visitproc visit, void *arg)80{81    Py_VISIT(self->foo);82    Py_VISIT(self->bar);83    return 0;84}85```8687Обработчик `tp_clear` должен иметь тип [`inquiry`](https://python-all.ru/3.2/c-api/gcsupport.html#inquiry) или *NULL*, если объект неизменяем.8889**int `(*inquiry)`([PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject) *\*self*)**9091Удаляет ссылки, которые могли создать циклические ссылки. Неизменяемые объекты могут не определять этот метод, так как они никогда не могут напрямую создавать циклические ссылки. Обратите внимание, что объект после вызова этого метода всё ещё должен быть корректным (нельзя просто вызвать [`Py_DECREF()`](https://python-all.ru/3.2/c-api/refcounting.html#Py_DECREF) на ссылку). Сборщик вызовет этот метод, если обнаружит, что этот объект вовлечён в циклическую ссылку.92