我在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.
答案 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错误。