我有两个cdef类B
和C
,它们的方法完全相同。它们之间唯一的区别是属性的类型:一个具有mpz
属性,另一个具有int
属性
我的第一个猜测是使用一个抽象类A
,它将被B
和C
覆盖。问题是Cython显然不希望我重写属性(另外,我应该为抽象类的属性指定哪种类型?)。我这样做的错误是:
------------------------------------------------------------
...
cdef class TestModularNumber:
cdef readonly mpz value, modulo
cdef class TestInheritance(TestModularNumber):
cdef readonly int value, modulo ^
------------------------------------------------------------
finite_field/testmodular.pxd:10:22: 'value' redeclared
我的第二个猜测是使用一个具有如下融合类型的类:
ctypedef fused mpz_or_int:
int
mpz
但是Cython抱怨我使用这种类型进行操作(比如%
,尽管它是为这两种类型定义的)。我得到的错误是:
------------------------------------------------------------
...
ctypedef fused mpz_or_int:
int
mpz
cdef class TestModularNumber:
cdef readonly mpz_or_int value, modulo ^
------------------------------------------------------------
finite_field/testmodular.pxd:12:36: Type is not specialized
------------------------------------------------------------
...
from gmpy2 import invert, powmod
cdef class TestModularNumber:
def __cinit__(self, mpz_or_int value, mpz_or_int modulo):
self.value = value
^
------------------------------------------------------------
finite_field/testmodular.pyx:7:12: Invalid use of fused types, type cannot be specialized
------------------------------------------------------------
...
if not self.has_modular_square_root():
raise ValueError(f"{self.value} is a non-residue modulo {self.modulo}.")
if self.value == 0 or self.value == 1:
return TestModularNumber(self.value, self.modulo)
if self.modulo % 4 == 3:
^
------------------------------------------------------------
finite_field/testmodular.pyx:145:23: Compiler crash in AnalyseExpressionsTransform
现在,我复制/粘贴了这两个类,但这是一个肮脏的黑客行为,显然,每次我必须修改这些类的方法时,我都会哭:)
我认为应该使用融合类型,但如何找到解决此问题的方法
由于Cython: templates in python class wrappers中解释的原因,这在Cython中通常不可用
cdef classes
不能有融合成员。在回答这个问题时,我建议使用“复制/粘贴”方法,但可能会尝试将其自动化对于这个特定的例子,我想知道您是否可以通过将实现从类中分离到单独的
cdef
融合函数来做得更好。首先为cdef classes
定义一个融合类我建议在类之间不要有任何继承关系,只要让它们实现一个(半)公共接口即可
然后,实际实现在非成员融合功能中:
显然,您可以将
cdef_pz_or_int
和pz_or_int
作为参数进行混合和匹配(如果需要的话),但是可能需要为所有组合生成有效代码我不是100%相信这会对你有用-如果不是,我很乐意删除它
相关问题 更多 >
编程相关推荐