使对象类型支持循环垃圾回收

    若要创建一个容器类,类型对象的 tp_flags 字段必须包含 并提供一个 tp_traverse 处理的实现。如果该类型的实例是可变的,还需要实现 。

    设置了此标志位的类型的对象必须符合此处记录的规则。为方便起见,下文把这些对象称为容器对象。

    容器类型的构造函数必须符合两个规则:

    TYPE PyObject_GC_New(TYPE, PyTypeObject **type)

    类似于 ,适用于设置了 Py_TPFLAGS_HAVE_GC 标签的容器对象。

    TYPE PyObject_GC_NewVar(TYPE, **type, Py_ssize_t size)

    类似于 PyObject_NewVar() ,适用于设置了 标签的容器对象。

    TYPE PyObject_GC_Resize(TYPE, PyVarObject **op, Py_ssize_t newsize)

    Resize an object allocated by . Returns the resized object or NULL on failure. op must not be tracked by the collector yet.

    把对象 op 加入到垃圾回收器跟踪的容器对象中。对象在被回收器跟踪时必须保持有效的,因为回收器可能在任何时候开始运行。在 tp_traverse 处理前的所有字段变为有效后,必须调用此函数,通常在靠近构造函数末尾的位置。

    void _PyObject_GC_TRACK( *op)

    PyObject_GC_Track() 的宏实现版本。它不能被用于扩展模块。

    3.6 版后已移除: 这个宏在 Python 3.8 中被移除。

    同样的,对象的释放器必须符合两个类似的规则:

    void PyObject_GC_Del(void *op)

    释放对象的内存,该对象初始化时由 或 PyObject_GC_NewVar() 分配内存。

    void PyObject_GC_UnTrack(void *op)

    从回收器跟踪的容器对象集合中移除 op 对象。 请注意可以在此对象上再次调用 以将其加回到被跟踪对象集合。 释放器 (tp_dealloc 句柄) 应当在 句柄所使用的任何字段失效之前为对象调用此函数。

    void (PyObject *op)

    3.6 版后已移除: 这个宏在 Python 3.8 中被移除。

    处理接收以下类型的函数形参。

    int (*visitproc)(PyObject object*, void arg*)

    传给 处理的访问函数的类型。object 是容器中需要被遍历的一个对象,第三个形参对应于 tp_traverse 处理的 arg 。Python核心使用多个访问者函数实现循环引用的垃圾检测,不需要用户自行实现访问者函数。

    处理必须是以下类型:

    int (*traverseproc)(PyObject self, visit*, void arg*)

    Traversal function for a container object. Implementations must call the visit function for each object directly contained by self, with the parameters to visit being the contained object and the arg value passed to the handler. The visit function must not be called with a NULL object argument. If visit returns a non-zero value that value should be returned immediately.

    为了简化 tp_traverse 处理的实现,Python提供了一个 宏。若要使用这个宏,必须把 tp_traverse 的参数命名为 visitarg

    void Py_VISIT( *o)

    If o is not NULL, call the visit callback, with arguments o and arg. If visit returns a non-zero value, then return it. Using this macro, tp_traverse handlers look like:

    The handler must be of the inquiry type, or NULL if the object is immutable.

    int ( *self)