Python扩展类型:super()在基类中找不到方法(也称为属性)
我是PyCXX,它是Python的C++包装器。 向新样式类添加方法的原始(工作)实现涉及为每个类创建一个“extern C”处理程序函数,用指向这些处理程序的指针填充PyMethodDef表,并将PyTypeObject的表->tp_方法放置到此表 <> >我用一个重写GETTARO的机制来替换这个机制,搜索我自己的数据,看看这个属性是否有一个相应的C++方法,如果这样的话,它就被封装成一个可调用的Python对象并返回它,否则推迟到pyObjtTeNoGeGETAuto.< /P> 如果我创建了一个新的\u样式\u类的实例,则此技术有效:Python扩展类型:super()在基类中找不到方法(也称为属性),python,derived-class,base-class,getattr,Python,Derived Class,Base Class,Getattr,我是PyCXX,它是Python的C++包装器。 向新样式类添加方法的原始(工作)实现涉及为每个类创建一个“extern C”处理程序函数,用指向这些处理程序的指针填充PyMethodDef表,并将PyTypeObject的表->tp_方法放置到此表 >我用一个重写GETTARO的机制来替换这个机制,搜索我自己的数据,看看这个属性是否有一个相应的C++方法,如果这样的话,它就被封装成一个可调用的Python对象并返回它,否则推迟到pyObjtTeNoGeGETAuto.< /P> 如果我创建了
# new_style_class is a C++ class deriving from ExtObj_new
_new_style_class = simple.new_style_class()
_new_style_class.func_noargs()
但是,如果我尝试从新样式类派生并从基调用func_noargs(),如下所示:
print( '--- Derived func ---' )
class Derived(simple.new_style_class):
def __init__( self ):
simple.new_style_class.__init__( self )
def derived_func( self ):
print( 'derived_func' )
print( vars(super()) )
super().func_noargs() # <-- AttributeError: 'super' object has no attribute 'func_noargs'
d = Derived()
d.derived_func()
print('----派生函数--')
派生类(简单。新的\u样式\u类):
定义初始化(自):
简单。新样式的类。初始化(self)
def派生函数(自):
打印('derived_func')
打印(变量(super())
super().func_noargs()#引用
已弃用,因此最好决定使用。但这根本不是正确的方法。查看Python的Objects/typeobject.c
源文件,您将找到super
类型的定义,以及定义类型方法的静态函数add\u methods
。这三者一起说明了为什么你会遇到问题
为什么不使用tp\u getattro
来“定义”方法
通常可以方便地将此字段设置为PyObject\u GenericGetAttr()
,这实现了查找对象属性的常规方法
因此,只为对象定义查找,而不为类型定义查找,但应为类型定义方法
如何定义方法
函数add_methods
迭代tp_methods
,使用PyDescr_NewMethod
定义每个方法(对于静态方法,PyCFunction_New
),并将其添加到类型对象的字典中
super
如何搜索方法
超级类型定义了tp\u getattro
。现在super().func\u noargs()
将触发超级对象中的func\u noargs
查找。这意味着将在每个相关超类型的字典中查找func_noargs
。如果未找到任何内容、请求了\uuuuu class\uuuuuuu
或未定义super
的第二个参数或None
,超级对象将在自身上调用PyObject\u GenericGetAttr
。因此,永远不会调用您的tp\u getattro
结论
如果您不喜欢原始(工作)解决方案,应将tp_getattro
中返回的函数放入类型对象的字典中。请向我们显示声明func_noargs()
的确切代码。如果它只是一个可调用的实例属性,super()
可能找不到它。换句话说,如果希望super()
工作,则此代码必须工作:simple.new\u style\u class.func\u noargs(实例)
。