Using self-defined Cython code from other Cython code

若如初见. 提交于 2019-12-03 12:32:59

Disclaimer: This question is very old and I am not sure the current solution would work for 2011 Cython code.

In order to cimport an extension class (cdef class) from another file you need to provide a .pxd file (also known as a definitions file) declaring all C classes, attributes and methods. See Sharing Extension Types in the documentation for reference.

For your example, you would need a file bendingForcesClass.pxd, which declares the class you want to share, as well as all cimports, module level variables, typedefs, etc.:

bendingForcesClass .pxd
# cimports
cimport numpy as np

# typedefy you want to share
ctypedef np.float64_t dtype_t
ctypedef np.complex128_t cplxtype_t
ctypedef Py_ssize_t index_t

cdef class bendingForcesClass:
    # declare C attributes
    cdef dtype_t bendingRigidity
    cdef np.ndarray matrixPrefactor
    cdef np.ndarray bendingForces

    # declare C functions
    cpdef np.ndarray calculate(self, np.ndarray membraneHeight)

    # note that __init__ is missing, it is not a C (cdef) function

All imports, variables, and attributes that now are declared in the .pxd file can (and have to be) removed from the .pyx file:

bendingForcesClass .pyx
import numpy as np

cdef class bendingForcesClass(object):

    def __init__(self, dtype_t bendingRigidity, np.ndarray[dtype_t, ndim=2] waveNumbersNorm):
        self.bendingRigidity = bendingRigidity
        self.matrixPrefactor = -self.bendingRigidity * waveNumbersNorm ** 2

    cpdef np.ndarray calculate(self, np.ndarray membraneHeight):
        cdef np.ndarray bendingForces
        bendingForces = self.matrixPrefactor * membraneHeight
        return bendingForces

Now your cdef class bendingForcesClass can be cimported from other Cython modules, making it a valid type identifier, which should solve your problem.

You need to use a declaration ".pxd" file and cimport. (Essentially, cimport happens at compile time, while import happens at run time so Cython can't make use of anything important).

Create "utils.pxd":

cdef class MyClass:
    cdef readonly int field
    cdef void go(self, int i)

"utils.pyx" now reads

cdef class MyClass:
    def __init__(self, field):
    self.field = field

cdef void go(self, int i):
    self.field = i

all declarations which have been in the pyx file go into the .pxd file.

Then in mymodule.pyx

from utils import MyClass
from utils cimport MyClass
# other code follows...

// Extended answer from here: Cython: using imported class in a type declaration

These are probably not the source of the error, but just to narrow down the problem, you might try to change the following:

Could it be that you are using bendingForces as the name of the variable here:

cpdef np.ndarray calculate( self, np.ndarray membraneHeight ) :
      cdef np.ndarray bendingForces
      bendingForces = self.matrixPrefactor * membraneHeight
      return bendingForces

and also the name of the member object here:

cdef class membraneClass( object ):
    cdef bendingForcesClass bendingForces

Also, bendingForcesClass is the name of the module as well as the class. Finally, how about making a ctypedef from the class bendingForcesClass?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!