У меня есть два класса 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
На данный момент я скопировал/вставил два класса, но это грязный хак, и, очевидно, каждый раз, когда мне приходится изменять метод этих классов, я плачу :)
Я думаю, что лучше всего использовать слитые типы, но как я могу найти обходной путь для этой проблемы?