假设我在python中定义了以下类
class A(object):
def __init__(self):
pass
def rockabye(self):
pass
class B(A):
def __init__(self):
pass
def iamOnlyinB(self):
pass
我正在尝试获取仅存在于B
中而不是从A
或object
继承的功能的列表。
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_methods
是NULL
。为什么呢还有什么可能的替代方法?
答案 0 :(得分:2)
指向
PyMethodDef
结构的以NULL结尾的静态数组的可选指针,声明了这种类型的常规方法。对于数组中的每个条目,将一个条目添加到包含方法描述符的类型的字典中(请参见下面的
tp_dict
)。此字段不受子类型继承(方法通过其他机制继承)。
换句话说,这些是创建类的扩展模块附加到该类的内置方法。
对于使用Python构建的类,没有内置方法,也没有创建扩展类的扩展模块,因此它始终为NULL
或为空。
您要执行的操作与在Python中执行的操作相同:
tp_dict
访问),或dir
或inspect.getmembers
之类的方法(与调用任何其他Python代码相同)。当然可以为您提供该类的所有属性(取决于您执行的操作,可能还包含所有继承的属性),因此,如果您只需要方法,则需要对其进行过滤。但是,您也可以使用Python中的方法进行操作。
由于“方法”是一个模棱两可的术语(它应该包括类方法和静态方法吗?当包装为方法时,包装器的作用就像函数一样,但是不是函数吗?等等……),您需要完全符合您要过滤的规则,并以与Python相同的方式应用它。 (有些东西,例如PyCallable_Check
,具有特殊的C API支持;对于其他任何事情,您都需要进行子类检查或调用Python函数。)