I've started to look into Cython as a way to speed up some code. One thing I would like to do is create a Cython class, which seems to be represented as a struct, to help create clean code.
I have the following folder structure:
+ test_package
+-- a.pxd
+-- a.pyx
+ setup.py
a.pxd
:
from libc.stdint cimport uint8_t
cdef class ClassA:
cdef readonly:
uint8_t a_attribute
uint8_t b_attribute
uint8_t c_attribute
cdef uint8_t get_a(self)
cdef uint8_t get_b(self)
cdef uint8_t get_c(self)
a.pyx
:
from libc.stdint cimport uint8_t
cdef class ClassA:
def __cinit__(self):
self.a_attribute = 0x00
self.b_attribute = 0x01
self.c_attribute = 0x02
cdef uint8_t get_a(self):
return self.a_attribute
cdef uint8_t get_b(self):
return self.b_attribute
cdef uint8_t get_c(self):
return self.c_attribute
cdef ClassA make_ClassA():
cdef ClassA A = ClassA()
A.a_attribute = 0x12
return A
setup.py
:
from setuptools import Extension, setup
from Cython.Build import cythonize
extensions = [Extension("test_package", ['test_package/*.pyx'])]
setup(
ext_modules=cythonize(extensions, annotate=True),
compiler_directives={'language_level' : "3"},
)
I can run python3.7 setup.py build_ext --inplace
to
build this. When I look at a.html
I see something like this:
Is there a reason that it's being converted to Python objects? For instance:
self.a_attribute = 0x00
if (__Pyx_PyObject_SetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_a_attribute, __pyx_int_0) < 0) __PYX_ERR(1, 5, __pyx_L1_error)
has the ability to reference __pyx_v_self
, but still converts it to a Python object. I can get a lot of my methods to compile to C code, but my biggest concern is for something like this:
The i, j, k
loops are compile to C, but the accessing of the struct variable is still a reference to a Python object.
Another option is I can do something like this:
But obviously this is still going to show as Python code based off everything I've shown above. So why is this? Am I using cdef class
incorrectly or is this just what happens when accessing cdef class
attributes?