获取C-Python内部的类方法的列表

时间:2018-08-29 21:23:11

标签: python cpython

假设我在python中定义了以下类

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。为什么呢还有什么可能的替代方法?

1 个答案:

答案 0 :(得分:2)

tp_methods是:

  

指向PyMethodDef结构的以NULL结尾的静态数组的可选指针,声明了这种类型的常规方法。

     

对于数组中的每个条目,将一个条目添加到包含方法描述符的类型的字典中(请参见下面的tp_dict)。

     

此字段不受子类型继承(方法通过其他机制继承)。

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

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


您要执行的操作与在Python中执行的操作相同:

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

当然可以为您提供该类的所有属性(取决于您执行的操作,可能还包含所有继承的属性),因此,如果您只需要方法,则需要对其进行过滤。但是,您也可以使用Python中的方法进行操作。

由于“方法”是一个模棱两可的术语(它应该包括类方法和静态方法吗?当包装为方法时,包装器的作用就像函数一样,但是不是函数吗?等等……),您需要完全符合您要过滤的规则,并以与Python相同的方式应用它。 (有些东西,例如PyCallable_Check,具有特殊的C API支持;对于其他任何事情,您都需要进行子类检查或调用Python函数。)