Python 在cython中组合多个装饰器

Python 在cython中组合多个装饰器,python,cython,Python,Cython,我发现这个有趣的问题很有趣 我想在赛昂做同样的事情。通常,我使用的Cython代码如下所示: @cython.boundscheck(False) @cython.wraparound(False) @cython.cdivision(True) cdef ar[dtype_t, ndim=2] sma_vec(ar[dtype_t, ndim=2] x, int m): cdef int n cdef Py_ssize_t i, j ... 或者 @cython.bo

我发现这个有趣的问题很有趣

我想在赛昂做同样的事情。通常,我使用的Cython代码如下所示:

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cdef ar[dtype_t, ndim=2] sma_vec(ar[dtype_t, ndim=2] x, int m):
    cdef int n
    cdef Py_ssize_t i, j
    ...
或者

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cpdef ar[dtype_t, ndim=2] sma_vec(ar[dtype_t, ndim=2] x, int m):
    cdef int n
    cdef Py_ssize_t i, j
    ...
我倾向于在几乎所有地方重复这三个装饰符
@cython.boundscheck(False)
@cython.wrapparound(False)
@cython.cdivision(True)

该页中给出的常规Python的解决方案是

def composed(*decs):
    def deco(f):
        for dec in reversed(decs):
            f = dec(f)
        return f
    return deco
对于Cython,我尝试执行以下操作:

cdef composed_for_cdef(*decs):
     cdef deco(f):
          for dec in reversed(decs):
              f = dec(f)
           return f
      return deco

但我在编译过程中遇到了一个错误:

cdef composed_for_cdef(*decs):
    cdef deco(f):
               ^
------------------------------------------------------------

stat\movavg.pyx:12:16: C function definition not allowed here
我甚至尝试了常规Python的解决方案(如上所述),但我得到了一个错误:

@composed(cython.boundscheck(False), cython.wraparound(False), cython.cdivision(True))
^
------------------------------------------------------------

stat\movavg.pyx:24:0: Cdef functions/classes cannot take arbitrary decorators.

组合装饰师不是这里的最佳方法。简单地说,加上

# cython: boundscheck=False
# cython: cdivision=True
# cython: wraparound=False
在源文件的头中(请参见Cython),这些选项将应用于所有已定义的函数。如有必要,可以使用适当的装饰器覆盖此默认行为

至于组合装饰器的问题,目前看来Cython不支持这一点。例如,即使使用python代码

cpdef composed_for_cpdef(*decs):
   def deco(f):
       for dec in reversed(decs):
           f = dec(f)
       return f
   return deco

我在Cython 0.22尚未支持的cpdef函数中编译
闭包时出错。

考虑到Cython的装饰器如何与编译器交互,我认为您尝试做的是不可能的。这就像试图将所有的
\uuuuu future\uuuuu
导入放在一个模块中,然后
import*
打开future语句。cython decorator是否真的返回了一个新的函数对象,或者增加了参数,然后返回它?@Eric,不确定我是否理解您的要求。我需要在
cimport cython
行之前或之后添加这些标题吗?
cpdef composed_for_cpdef(*decs):
   def deco(f):
       for dec in reversed(decs):
           f = dec(f)
       return f
   return deco