C语言中的tp_as_mapping等方法何时被调用?

3 投票
1 回答
504 浏览
提问于 2025-04-17 15:20

C语言中的PyObject结构体包含了几个字段,分别是tp_as_numbertp_as_sequencetp_as_mapping。这些字段在什么情况下会被使用呢?有没有人能提供一些示例Python代码,展示这些C语言的方法是如何被调用的?

1 个回答

3

这些方法相当于Python中的特殊方法,在相同的情况下被调用。比如说,当你执行 a + b 时,如果 a 是一个扩展类型,就会调用 tp_as_number->nb_add。这就相当于 __add__ 方法。以 inplace_* 开头的函数则对应于 __i*__ 方法。

需要注意的是,__r*__ 方法的实现其实就是把参数调换到普通函数中去。因此,当你写 5 + a,其中 a 是一个扩展类型时,系统会先尝试调用数字版本的 nb_add,如果失败了,再尝试调用 anb_add,这时会把 5 作为第一个参数,a 作为第二个参数。

对于 tp_as_mappingtp_as_sequence 结构也是一样的。mp_lengthsq_length 函数是由内置函数 len 调用的,它们相当于 __len__ 方法。理论上,你可以为 mp_lengthsq_length 实现不同的函数,在这种情况下,sq_length 的优先级更高(这一点可以从源代码中看出,尽管我不知道这个行为是否有文档说明)。

另外需要注意的是,比如说 + 运算符可以通过不同的函数来实现。在尝试 nb_add 之后,会调用 sq_concat,因此一个扩展类型可以支持 + 运算符,而不需要设置 nb_add 函数。

撰写回答