我目前正在尝试优化我的Python程序,并开始使用Cython,以减少函数调用开销,也许以后还会包括优化的C库函数。在
所以我遇到了第一个问题:
我在代码中使用合成来创建一个更大的类。到目前为止,我已经将一个Python类转换为Cython(这已经足够困难了)。代码如下:
import numpy as np
cimport numpy as np
ctypedef np.float64_t dtype_t
ctypedef np.complex128_t cplxtype_t
ctypedef Py_ssize_t index_t
cdef class bendingForcesClass(object):
cdef dtype_t bendingRigidity
cdef np.ndarray matrixPrefactor
cdef np.ndarray bendingForces
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
在我编写的Python/Cython类中,我调用了类方法calculate
,因此在我的组合类中我有以下(简化的)代码:
我发现cpdef
使方法/函数可以从Python和Cython调用,这很好而且很有效,只要我不尝试预先定义self.bendingForces
的类型,根据the documentation (Early Binding For Speed)这是必要的,以便消除函数调用开销。我尝试了以下方法,但没有效果:
from bendingForcesClass import bendingForcesClass
from bendingForcesClass cimport bendingForcesClass
cdef class membraneClass(object):
cdef bendingForcesClass bendingForces
def __init__(self, systemSideLength, lowerCutoffLength, bendingRigidity):
self.bendingForces = bendingForcesClass(bendingRigidity, self.waveNumbers.norm)
def calculateForces(self, heightR):
return self.bendingForces.calculate(heightR)
在尝试用Cython构建membraneClass.pyx
时,我得到了一个错误:
membraneClass.pyx:18:6: 'bendingForcesClass' is not a type identifier
building 'membraneClass' extension
请注意,声明位于两个单独的文件中,这使得这一点更加困难。在
所以我该怎么做?如果有人能给我一个指针,我会非常感谢,因为除了上面给出的链接之外,我找不到任何关于这个的信息。在
谢谢并致以诚挚的问候!在
这些可能不是错误的来源,但为了缩小问题的范围,您可以尝试更改以下内容:
可能是您在这里使用
bendingForces
作为变量名:这里还有成员对象的名称:
^{pr2}$另外,
bendingForcesClass
是模块和类的名称。最后,从类bendingForcesClass
生成一个ctypedef
怎么样?在您需要使用声明“.pxd”文件和cimport。(本质上,cimport发生在编译时,而导入发生在运行时,所以Cython不能利用任何重要的东西)。在
^{pr2}$pyx文件中的所有声明都将放入.pxd文件中。在
//从这里扩展答案: Cython: using imported class in a type declaration
免责声明:这个问题非常古老,我不确定当前的解决方案是否适用于2011年Cython代码。在
为了从另一个文件cimport一个扩展类(cdef类),您需要提供一个声明所有C类、属性和方法的.pxd文件(也称为定义文件)。请参阅文档中的Sharing Extension Types以供参考。在
例如,您需要一个文件
弯曲力class.pxdbendingForcesClass.pxd
,该文件声明要共享的类,以及所有cimports、模块级变量、typedef等:现在在
弯曲力class.pyx ^{pr2}$.pxd
文件中声明的所有导入、变量和属性都可以(并且必须)从.pyx
文件中删除:现在您的cdef类
bendingForcesClass
可以从其他Cython模块cimported,使其成为有效的类型标识符,这应该可以解决您的问题。在相关问题 更多 >
编程相关推荐