Два раздела документа Python 2.7, упомянутые добавлением сборник циклических мусора (CGC) поддержка объектов контейнера, определенных в модулях расширения.Правильная циклическая сборка мусора в модулях расширения
Python/C API Reference Manual дает два правила, т.е.
- памяти для объекта должна быть выделена с помощью
PyObject_GC_New()
илиPyObject_GC_NewVar()
.- После того, как все поля, которые могут содержать ссылки на другие контейнеры, будут инициализированы, он должен вызвать
PyObject_GC_Track()
.
В то время как в Extending and Embedding the Python Interpreter, для Noddy
например, кажется, что добавление Py_TPFLAGS_HAVE_GC
флага и заполнение tp_traverse
и tp_clear
слотов будет вполне достаточно, чтобы обеспечить поддержку CGC. И два вышеприведенных правила НЕ применяются практически.
Когда я изменил Noddy
пример на самом деле следовать правилам PyObject_GC_New()
/PyObject_GC_Del()
и PyObject_Track()
/PyObject_GC_UnTrack()
, он неожиданно поднял ошибку утверждение говоря,
Модули/gcmodule.c: 348: visit_decref: Утверждение «дс -> gc.gc_refs! = 0 "не удалось. refcount был слишком мал
Это приводит к моему путанице в правильном/безопасном способе реализации CGC. Может ли кто-нибудь давать советы или, предпочтительно, neat пример контейнерного объекта с поддержкой CGC?
Спасибо за ответ. Я изучаю возможность того, что некоторые версии API-интерфейса PyObject_GC_New() не могут корректно обрабатывать подтипы, что является причиной AssertionError. – liuyu