I want to implement the abstract class in .pyx files. And my python code (written in abst_cls2main.py) wants to import a class inherited Child(written in abst_cls2child.pyx) the abstract class Base(written in abst_cls2base.pyx).
# FILENAME: abst_cls2child.pyx
#cython: language_level=3
# distutils: language = c++
cimport cython
# from abst_cls1base cimport Base
# from abst_cls1base import Base
# cimport abst_cls1base
import pyximport;
pyximport.install()
from abst_cls2base import Base
# from abst_cls2base cimport Base
print(f"Loading {__file__}")
cdef class Child(Base):
def __init__(self):
super().__init__()
self.show()
print(f"Loaded {__file__}")
#FILENAME: abst_cls2base.pyx
#cython: language_level=3
# distutils: language = c++
import pyximport;
pyximport.install()
cdef class Base:
cdef int a
def show(self):
print("Base class called")
# FILENAME: abst_cls2main.py
import pyximport;
pyximport.install()
# cimport cython
from abst_cls2child import Child
a = Child()
If the above files(abst_cls2child.pyx,abst_cls2base.pyx) are described into one .pyx file. The files(one.pyx, abst_cls2main.py) works just as I expected.
most of the info taken from cython documentation sharing declarations and cython documentation extension types
you need to declare a header file for abst_cls2base.pyx
with name abst_cls2base.pxd
which defines the class
# FILENAME: abst_cls2base.pxd
# cython: language_level=3
# distutils: language = c++
cdef class Base:
cdef int a
cpdef show(self)
now you need to modify the implementation of Base
and remove the data attributes
#FILENAME: abst_cls2base.pyx
# cython: language_level=3
# distutils: language = c++
cdef class Base:
cpdef show(self):
self.a += 1
print("a =",self.a)
print("Base class called")
and your second module needs to cimport it, when it sees the cimport it will look for the class in the header abst_cls2base.pxd
and see it's an extension type
# FILENAME: abst_cls2child.pyx
#cython: language_level=3
# distutils: language = c++
from abst_cls2base cimport Base
print(f"Loading {__file__}")
cdef class Child(Base):
def __init__(self):
super().__init__()
self.show()
self.increment_a()
cpdef increment_a(self):
self.a += 1
print("a =",self.a)
print(f"Loaded {__file__}")
and for your main python script
# FILENAME: abst_cls2main.py
import pyximport
pyximport.install()
from abst_cls2child import Child
a = Child()
a = 1
Base class called
a = 2
now the print
statements in the global scope aren't executed ... mostly because cython code is compiled, not interpreted like python, it doesn't run in the same order that it is written, but the rest of the code works.
just note that i converted the function show
to cpdef
and redeclared it in the header file so it can be called without invoking the interpreter within cython, converting it back to def
will make it called through the interpreter which is against the point of having cython modules ...