让C扩展类从Python类继承
我有一个Python类让C扩展类从Python类继承,python,python-c-api,Python,Python C Api,我有一个Python类AbstractFoo,它使用@abc.abstractmethod来定义两个抽象方法 为了获得更高的性能,大部分工作是在C中作为Python扩展类CFoo实现的,因此我想做的是从AbstractFoo继承该扩展类 然而,我没有找到一种方法来实现这一点,而是走了另一条路:在C中作为“普通”类实现它,并拥有一个类ConcreteFoo(AbstractFoo,CFoo),它继承自抽象Python和扩展类 然而现在ABC的“保护”并没有起作用:即使方法丢失,也没有抛出错误。我在
AbstractFoo
,它使用@abc.abstractmethod
来定义两个抽象方法
为了获得更高的性能,大部分工作是在C中作为Python扩展类CFoo
实现的,因此我想做的是从AbstractFoo
继承该扩展类
然而,我没有找到一种方法来实现这一点,而是走了另一条路:在C中作为“普通”类实现它,并拥有一个类ConcreteFoo(AbstractFoo,CFoo)
,它继承自抽象Python和扩展类
然而现在ABC的“保护”并没有起作用:即使方法丢失,也没有抛出错误。我在中找到了一个解决方案,并添加了一个新的new
方法,而不是PyType\u GenericNew
(暂时忽略空部分的引用计数):
但是现在ABC检查总是触发:TypeError:无法用抽象方法实例化抽象类ConcreteFoo…
但是检查
dir(ConcreteFoo)
会显示它抱怨的方法
有没有一种方法可以让myAbstractFoo
的ABC检查子类在C中实现这些方法
编辑:更多代码:
class AbstractFoo(abc.ABC):
@abc.abstractmethod
def register(self):
pass
# ...
#...
class ConcreteFoo(AbstractFoo, CFoo):
def __init__(self, arg):
AbstractFoo.__init__(self)
CFoo.__init__(self, arg)
您必须使
CFoo
成为第一个基类。这与C-API关系不大,也适用于纯Python版本:如果您定义
class CFoo:
def register(self):
return "CFoo.register"
然后
失败了,但是
class ConcreteFoo(CFoo, AbstractFoo):
工作
这对于
\uu mro\uuu
来说是有意义的,您可以通过使寄存器
不是抽象方法来测试这一点。您会发现中第一个基类的方法优先使用。当第一个基类是AbstractFoo
时,这是一个首先被发现的抽象方法,因此它失败了。我认为\uuuuuAbstractMethods\uuuu
是通过ABCMeta
在创建类型时设置的。因此,您需要确保在定义类型ConcreteFoo
时调用该元类,而不是PyType\u type
。不幸的是,您没有显示这段代码…我不知道您的代码是什么意思。未显示的代码几乎就是您使用的基本样板代码。我在上面添加了ConcreteFoo
的定义和AbstractFoo
的重要部分——我有点误解,认为您是在用C声明ConcreteFoo
(例如,使用PyObject\u调用(PyType\u Type,
)这确实让事情变得更清楚了register
对于一个抽象方法名来说是一个危险的选择,因为它与。这是正确的并且有效,谢谢。我发现这与直觉相反,因为我希望从lft到右继承工作。为了完整性:您是否碰巧有到官方文档的链接?也许吧(虽然它显然很快就变得非常详细了)。也许可以这样考虑:所有基类中的所有方法仍然存在,它从左到右搜索以找到合适的方法(而不是“方法被添加的新基类覆盖”,我认为这是您所假设的)
class ConcreteFoo(AbstractFoo, CFoo):
class ConcreteFoo(CFoo, AbstractFoo):