LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 252|回复: 0

python - 递归控制

[复制链接]
发表于 2024-1-23 17:51:57 | 显示全部楼层 |阅读模式


这两个函数提供了一种在 C 层级上进行安全的递归调用的方式,在核心模块与扩展模块中均适用。 当递归代码不一定会发起调用 Python 代码(后者会自动跟踪其递归深度)时就需要用到它们。 它们对于 tp_call 实现来说也无必要因为 调用协议 会负责递归处理。

int Py_EnterRecursiveCall(const char *where)
属于 稳定 ABI 自 3.9 版开始.
标记一个递归的 C 层级调用即将被执行的点位。

如果定义了 USE_STACKCHECK,此函数会使用 PyOS_CheckStack() 来检查 OS 栈是否溢出。 在这种情况下,它将设置一个 MemoryError 并返回非零值。

随后此函数将检查是否达到递归限制。 如果是的话,将设置一个 RecursionError 并返回一个非零值。 在其他情况下,则返回零。

where 应为一个 UTF-8 编码的字符串如 " in instance check",它将与由递归深度限制所导致的 RecursionError 消息相拼接。

在 3.9 版本发生变更: 此函数现在也在 受限 API 中可用。

void Py_LeaveRecursiveCall(void)
属于 稳定 ABI 自 3.9 版开始.
结束一个 Py_EnterRecursiveCall()。 必须针对 Py_EnterRecursiveCall() 的每个 成功的 发起调用操作执行一次调用。

在 3.9 版本发生变更: 此函数现在也在 受限 API 中可用。

正确地针对容器类型实现 tp_repr 需要特别的递归处理。 在保护栈之外,tp_repr 还需要追踪对象以防止出现循环。 以下两个函数将帮助完成此功能。 从实际效果来说,这两个函数是 C 中对应 reprlib.recursive_repr() 的等价物。

int Py_ReprEnter(PyObject *object)
属于 稳定 ABI.
在 tp_repr 实现的开头被调用以检测循环。

如果对象已经被处理,此函数将返回一个正整数。 在此情况下 tp_repr 实现应当返回一个指明发生循环的字符串对象。 例如,dict 对象将返回 {...} 而 list 对象将返回 [...]。

如果已达到递归限制则此函数将返回一个负正数。 在此情况下 tp_repr 实现通常应当返回 NULL。

在其他情况下,此函数将返回零而 tp_repr 实现将可正常继续。

void Py_ReprLeave(PyObject *object)
属于 稳定 ABI.
结束一个 Py_ReprEnter()。 必须针对每个返回零的 Py_ReprEnter() 的发起调用操作调用一次。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表