获取 C-Python 中的 class 方法列表

Get a list of class methods inside C-Python

假设我在 python 中定义了一个 class,如下所示

class A(object):
    def __init__(self):
        pass
    def rockabye(self):
        pass

class B(A):
    def __init__(self):
        pass
    def iamOnlyinB(self):
        pass

我正在尝试获取仅存在于 B 而不是从 Aobject.

继承的函数列表
PyTypeObject* l_typeObject = <a function out of scope of the question>

for (int i = 0; true; i++)
    {
        PyMethodDef method_def = l_typeObject->tp_methods[i];
        if(method_def.ml_name == NULL)
            break;
        std::cout << method_def.ml_name <<std::endl;

    }

我总是发现 l_typeObject->tp_methodsNULL。为什么 ?有哪些可能的替代方法?

tp_methods 是:

An optional pointer to a static NULL-terminated array of PyMethodDef structures, declaring regular methods of this type.

For each entry in the array, an entry is added to the type’s dictionary (see tp_dict below) containing a method descriptor.

This field is not inherited by subtypes (methods are inherited through a different mechanism).

换句话说,这些是由创建它的扩展模块附加到 class 的内置方法。

对于 Python 中内置的 class,没有内置方法,也没有创建它的扩展模块,因此它将始终为 NULL 或为空。


你想做的和你在Python做的一样:

  • 要么查看 class 的字典(您可以通过 tp_dict 访问),要么
  • 调用 dirinspect.getmembers 之类的方法(与调用任何其他 Python 代码的方法相同)。

当然,这会让你获得 class 的 all 属性(取决于你所做的,也可能是所有 inherited属性),因此如果您只需要 方法 ,则需要对其进行过滤。但是您也可以按照 Python 中的方式执行此操作。

因为“方法”是一个模棱两可的术语(它应该包括 class 方法和静态方法吗?包装器在绑定为方法时就像函数一样,但不是函数呢?等等…),您需要准确地提出要过滤的规则,并按照与 Python 相同的方式应用它。 (一些东西,比如 PyCallable_Check,有特殊的 C API 支持;对于其他任何东西,你将进行 subclass 检查或调用 Python 函数。)