使用Cython装饰器的纯Python:如何在模块级别获取属性访问权限

时间:2013-03-01 08:56:55

标签: python cython

我想用Cython装饰器编写一些纯Python,但是当我将NONE.PY重命名为NONE.PYX时,我遇到了错误。 要解决此问题,我需要使用没有装饰器的纯python定义调用来包装每个属性。 我想知道为什么......

此处模块为none.pyx(如果将其重命名为none.py,则根本没有问题)

import cython

@cython.cfunc
@cython.returns(cython.double)
@cython.locals(n=cython.int,i=cython.int,r=cython.int)
def ccrange(n):
  r=0
  for i in range(n):
    r+=i
  return r

def crange(n):  return ccrange(n)

和python测试文件test_none.py:

import pyximport; pyximport.install()
import none
n=10000
print ">>pure python call>>",none.crange(n)
print ">>cython call>>",none.ccrange(n)

结果为none.pyx:

  
    

纯python电话>> 49995000.0     cython call>>     Traceback(最近一次调用最后一次):     文件“C:\ Users \ damien \ python4d \ bacoland \ test_none.py”,第6行,in        print“>> cython call>>”,none.ccrange(n)
    AttributeError:'module'对象没有属性'ccrange'

  

将none.pyx重命名为none.py,给:

  
    

纯python电话>> 49995000     cython call>> 49995000

  

感谢您的帮助!有一个NiceDay: - )

编辑: 避免装饰者@ cython.cfunc打破了cython的速度优势...... 使用和不使用@ cython.cfunc考虑以下代码:

@cython.cfunc
@cython.returns(cython.double)
@cython.locals(n=cython.int)
def fibo_c(n):
  if n == 0 or n == 1:
      return n
  return fibo_c(n-2) + fibo_c(n-1)

2 个答案:

答案 0 :(得分:2)

@cython.cfunc装饰器相当于cdef一个函数(有关详细信息,请参阅here),因此只能在C代码中访问此函数。因此,要使其可以从Python中访问,请删除@cython.cfunc

答案 1 :(得分:1)

您应该将@cython.cfunc(相当于cdef,即只能从C调用)替换为@cython.ccall(相当于cpdef,即使用慢速Python可访问调用约定和快速C调用约定。)