Cython中cpdef函数使用lambda表达式报错问题咨询
解决Cython中cpdef函数无法使用lambda的问题
我完全懂你的困惑——明明Cython变更日志说支持lambda,可放到cpdef函数里就报错,偏偏cdef函数里又能正常跑。这其实是cpdef函数的特殊机制在搞鬼:cpdef会同时生成Python接口和C接口,当你把lambda作为参数传给sorted这类Python内置函数时,Cython在生成C兼容代码时会遇到类型冲突——lambda是纯Python层面的匿名函数,而cpdef的C接口部分对类型要求更严格,目前Cython的实现还没完全适配这种场景。
给你几个实用的解决方案:
方案1:显式将lambda声明为Python对象
在cpdef函数里,先把lambda赋值给object类型的变量,再传给sorted,让Cython明确把它当作Python对象处理,绕过类型推断的问题:
%%cython cimport numpy as np import numpy as np cpdef hoo(): a = np.random.randint(1,10,10) object key_func = lambda x: x%np.pi b = sorted(a, key=key_func) return(b)
方案2:把lambda逻辑封装到cdef辅助函数
既然cdef函数能正常用lambda,我们可以把需要用到lambda的逻辑单独封装到cdef函数里,再让cpdef调用它:
%%cython cimport numpy as np import numpy as np cdef _sort_with_lambda(np.ndarray a): return sorted(a, key=lambda x: x%np.pi) cpdef hoo(): a = np.random.randint(1,10,10) b = _sort_with_lambda(a) return(b)
方案3:禁用局部代码的类型推断
你可以在代码块前加注释,告诉Cython不对该部分做严格类型推断,强制按Python对象逻辑处理:
%%cython cimport numpy as np import numpy as np cpdef hoo(): a = np.random.randint(1,10,10) # cython: infer_types=False b = sorted(a, key=lambda x: x%np.pi) return(b)
另外记得确认你的Cython版本是支持lambda的(至少0.19以上,现在主流版本都满足),可以通过cython --version命令查看。
内容的提问来源于stack exchange,提问作者Manish Goel
相关产品推荐
相关产品推荐

