在cython中组合多个装饰器

时间:2015-05-22 22:31:46

标签: python cython

我在combine multiple decorators in python to a single decorator上找到了这个有趣的问题。

我想在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.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.wraparound(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

cpdef composed_for_cpdef(*decs):
     cpdef 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.

1 个答案:

答案 0 :(得分:2)

组合装饰器不是这里的最佳选择。简单地说,添加,

# cython: boundscheck=False
# cython: cdivision=True
# cython: wraparound=False

在源文件的标题中(请参阅Cython compiler directives),这些选项将应用于所有已定义的函数。如有必要,可以使用适当的装饰器来覆盖此默认行为。

关于组合的装饰器问题,目前看来这在Cython中不受支持。例如,即使使用大多数python代码,

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

我在编译closures inside cpdef functions not yet supported时遇到Cython 0.22错误。