Cython"不允许在常量表达式中",boundscheck False不起作用

Tak*_*oda 4 python cython python-3.x cythonize

我对Cython比较新,遇到了一个我的研究失败的错误(我在spyder中使用Python3而我的Sython版本是0.26)

我试过这个:

import cython

@cython.boundscheck(False)
def boundtest():
     cdef int r=4
     cdef double l[3]
Run Code Online (Sandbox Code Playgroud)

它工作正常.但后来我尝试了这个:

import cython

@cython.boundscheck(False)
def boundtest():
     cdef int r=4
     cdef double l[r]
Run Code Online (Sandbox Code Playgroud)

我收到错误

[1/1] Cythonizing test.pyx

Error compiling Cython file:
------------------------------------------------------------
...
import cython

@cython.boundscheck(False)
def boundtest():
     cdef int r=4
     cdef double l[r]
                   ^
------------------------------------------------------------

test.pyx:13:20: Not allowed in a constant expression
Run Code Online (Sandbox Code Playgroud)

由于找到相关的stackexchange帖子并阅读了Kurt W. Smith的Cython书,因此添加了装饰器.据我所知,这应该告诉Cython不要担心可能因动态索引变量而导致的超出界限错误,但由于某种原因它不会.我也尝试在编译器选项中更改boundscheck并在全局范围内无效.

如果不是因为Cython文档声称是最新的,我会认为boundscheck已被折旧.

UPDATE

我意识到我用过import Cython而不是cimport cython.我又试过了

cimport cython
Run Code Online (Sandbox Code Playgroud)

但得到同样的错误.

更新2

在类似的说明代码

cdef int N = 3
cdef double[:] lout = array.array('d', N)
Run Code Online (Sandbox Code Playgroud)

抛出错误

TypeError: 'int' object is not iterable
Run Code Online (Sandbox Code Playgroud)

我假设出于同样的原因,C不能处理(可能)动态数组分配.相反,我们必须使用

cdef double[:] lout = numpy.empty(N, 'd')
Run Code Online (Sandbox Code Playgroud)

我假设有一条线在将N放入C阵列之前将N转换为静态类型

MSe*_*ert 10

失败与失败无关cython.boundscheck.

Boundchecking只是检查您是否尝试访问不存在的数组元素.例如,如果你有一个4号数组,并尝试访问元素5 - boundscheck(True)它将给你一个异常,boundscheck(False)它将导致未定义的行为(可能导致分段错误).

编译失败的原因是另一个:你不能创建一个动态长度的静态数组!元素的数量需要在编译时知道,这只是强制执行(我猜).

但是,您可以定义r编译时知道:

DEF r=4

cimport cython

@cython.boundscheck(False)
def boundtest():
    cdef double l[r]
Run Code Online (Sandbox Code Playgroud)

但是,您可以简单地创建一个NumPy数组并将其存储在memoryview变量中:

cimport cython
import numpy as np

@cython.boundscheck(False)
def boundtest():
    cdef int r=4
    cdef double[:] l = np.empty(r, dtype=np.double)
Run Code Online (Sandbox Code Playgroud)