1

我想用 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调用>> Traceback(最近一次调用最后):文件“C:\Users\damien\python4d\bacoland\test_none.py”,第6行,打印“>>cython调用>>”, none.ccrange(n)
AttributeError: 'module' 对象没有属性 'ccrange'

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

纯python调用>> 49995000 cython调用>> 49995000

感谢帮助!祝你今天过得愉快 :-)

编辑:避免装饰器@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)
4

2 回答 2

2

@cython.cfuncdecorator 等价于cdefing 一个函数(详见此处),因此该函数只能在C代码中访问。因此,要使其可以从 Python 访问,请摆脱@cython.cfunc.

于 2013-03-01T09:56:35.123 回答
2

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

于 2013-07-15T09:36:35.200 回答