【发布时间】:2015-04-13 11:58:14
【问题描述】:
我在 cython 中编写了一个类,并且我有一个方法可以检查类对象是否没有属性。如果文件存在,它会从文件中读取此对象,或者它会计算数组或内存视图的值并将结果保存在文件中。以下是我的部分代码:
from __future__ import division
import numpy as np
cimport numpy as np
cimport cython
from libc.stdio cimport FILE, fopen, fwrite, fscanf, fclose, stdout, stderr
cdef extern from "math.h":
double exp(double) nogil
double log(double) nogil
cdef class NFW(object):
cdef object ks, source_redshift
cdef const char* path
def __cinit__(self, char* path, double[::1] zs=None, *args):
self.path=path
if self.path==NULL:
raise ValueError("Could not find a path to the file which contains the table of diameter distances")
if zs is None:
raise ValueError("You must give an array !")
self.source_redshift=zs
@cython.cdivision(True)
@cython.boundscheck(False)
@cython.wraparound(False)
cdef void get_ks(self):
cdef FILE* handle
cdef Py_ssize_t i, nz
nz = len(self.source_redshift)
cdef double* array[nz]
if not hasattr(self, 'ks'): # does self.ks not exist?
try:
## first, check for existing file, see if we can load in self.ks
handle = fopen(self.path, "r")
if handle == NULL:
raise ValueError("cannot open file {}".format(self.path))
for i from nz > i >= 0:
fscanf(handle,"%f",&array[i])
fclose(handle)
self.ks= &array
except IOError:
self.ks = self.calculate_ks()
@cython.cdivision(True)
@cython.boundscheck(False)
@cython.wraparound(False)
cdef double[::1] calculate_ks(self):
cdef Py_ssize_t i, nz
nz = len(self.source_redshift)
cdef double[::1] k_s = np.zeros(nz,dtype=np.float64_t)
for i from nz > i >= 0:
k_s[i]= log((1.+self.source_redshift[i])/(1.-self.source_redshift[i]))
#write the calculated k_s in a file
cdef FILE* handle=<FILE *>fopen(self.path,"wb")
fwrite(k_s,sizeof(k_s),1,handle)
fclose(handle)
return k_s
我对 c 不是很熟悉,我是一个 cython 初学者。我收到以下错误消息,我不知道如何在指针数组中读取 cython 中的文件并将其转换为类的实例的最佳方法。我应该强调我正在寻找在 cython 中执行文件读取的最快方法。
Error compiling Cython file:
------------------------------------------------------------
...
@cython.wraparound(False)
cdef void get_ks(self):
cdef FILE* handle
cdef Py_ssize_t i, nz
nz = len(self.source_redshift)
cdef double* array[nz]
^
------------------------------------------------------------
WLUtilities.pyx:413:30: Not allowed in a constant expression
Error compiling Cython file:
------------------------------------------------------------
...
raise ValueError("cannot open file {}".format(self.path))
for i from nz > i >= 0:
fscanf(handle,"%f",&array[i])
fclose(handle)
self.ks= &array
^
------------------------------------------------------------
WLUtilities.pyx:424:24: Cannot convert 'double *(*)[__pyx_v_nz]' to Python object
Error compiling Cython file:
------------------------------------------------------------
...
k_s = np.zeros(nz,dtype=np.float64_t)
for i from nz > i >= 0:
k_s[i]= self.__ks(self.source_redshift[i])
#write the calculated k_s in a file
cdef FILE* handle=<FILE *>fopen(self.path,"wb")
fwrite(k_s,sizeof(k_s),1,handle)
^
------------------------------------------------------------
WLUtilities.pyx:440:19: Cannot convert Python object to 'const void *'
【问题讨论】:
标签: c arrays class pointers cython