C语言中的tp_as_mapping等方法何时被调用?
C语言中的PyObject结构体包含了几个字段,分别是tp_as_number
、tp_as_sequence
和tp_as_mapping
。这些字段在什么情况下会被使用呢?有没有人能提供一些示例Python代码,展示这些C语言的方法是如何被调用的?
1 个回答
3
这些方法相当于Python中的特殊方法,在相同的情况下被调用。比如说,当你执行 a + b
时,如果 a
是一个扩展类型,就会调用 tp_as_number->nb_add
。这就相当于 __add__
方法。以 inplace_*
开头的函数则对应于 __i*__
方法。
需要注意的是,__r*__
方法的实现其实就是把参数调换到普通函数中去。因此,当你写 5 + a
,其中 a
是一个扩展类型时,系统会先尝试调用数字版本的 nb_add
,如果失败了,再尝试调用 a
的 nb_add
,这时会把 5
作为第一个参数,a
作为第二个参数。
对于 tp_as_mapping
和 tp_as_sequence
结构也是一样的。mp_length
和 sq_length
函数是由内置函数 len
调用的,它们相当于 __len__
方法。理论上,你可以为 mp_length
和 sq_length
实现不同的函数,在这种情况下,sq_length
的优先级更高(这一点可以从源代码中看出,尽管我不知道这个行为是否有文档说明)。
另外需要注意的是,比如说 +
运算符可以通过不同的函数来实现。在尝试 nb_add
之后,会调用 sq_concat
,因此一个扩展类型可以支持 +
运算符,而不需要设置 nb_add
函数。