假设我定义了下面的Cython类
cdef class Kernel:
cdef readonly double a
def __init__(self, double a):
self.a = a
cdef public double GetValue(self, double t):
return self.a*t
现在我想定义另一个扩展类型,它以一系列内核作为属性。比如:
^{pr2}$但是,这不起作用。首先,我需要将Kernel[:]
替换为object[:]
,否则我从gcc
得到以下错误
‘PyObject’ has no member named ‘__pyx_vtab’
如果我使用object[:]
所有的编译都很好,但是当我试图访问GetValue
方法时出现了一个错误:
AttributeError: "AttributeError: "'cytest.Kernel' object has no attribute 'GetValue'" in 'cytest.Model.Run'
cdef
方法Run
访问cdef
的cdef
方法,而无需Python开销。在目前,我使用以下解决方案,但不满足上述要求:
cdef class Kernel:
cdef readonly double a
def __init__(self, double a):
self.a = a
cpdef public double GetValue(self, double t):
return self.a*t
cdef class Model:
cdef readonly object[:] kernels
cdef unsigned int n_kernels
def __init__(self, object[:] ker):
self.kernels = ker
self.n_kernels = ker.shape[0]
def Run(self, double t):
cdef int i
cdef double out=0.0
for i in range(self.n_kernels):
out += self.kernels[i].GetValue(t)
return out
也就是说,我将内核类的方法声明为cpdef
,这样就可以从Python访问它们并使用object[:]
。在
在Cython中有没有一种方法可以在不增加Python开销的情况下实现上述第1点和第2点?在
提前谢谢你的时间。在
NB:我事先不知道序列的长度。在
根据@DavidW的建议,我修改了代码如下
# module cytest
import cython
cdef class Kernel:
cdef readonly double a
def __init__(self, double a ):
self.a = a
cdef public double GetValue(self, double t):
return self.a*t
cdef class Model:
cdef readonly Kernel[:] kernels
### added this attribute
cdef Kernel k
cdef unsigned int n_kernels
def __cinit__(self, Kernel[:] ker):
self.kernels = ker
self.n_kernels = ker.shape[0]
cpdef double Run(self, double t):
cdef int i
cdef double out=0.0
for i in range(self.n_kernels):
# now i assign to the new attribute each time
# and access the cdef method from it
self.k = self.kernels[i]
out += self.k.GetValue(t)
return out
现在它可以很好地编译和运行(比我以前的解决方法更快),即使我在访问Kernel[:]
属性时仍然有一些python开销。在
我在这里给出了一个生成和调用Model
的示例
import cytest
import numpy as np
ker_list = [cytest.Kernel(i*1.0) for i in range(3)]
# transform it to a numpy array
# to be able to pass it to the 'Model' constructor
ker_arr = np.array(ker_list)
# create a model instance
model = cytest.Model(ker_arr)
# call the method Run
print model.Run(1.0)
目前没有回答
相关问题 更多 >
编程相关推荐