Cython是否支持C++闭包?如何用闭包实现vector排序?
Cython调用C++ sort配合闭包的解决方案
核心结论
当前最新版Cython不支持直接在.pyx源码中书写C++原生的lambda闭包语法,报错Expected ')', found 'a'是Cython解析器无法识别C++ lambda的[]语法导致的。
可行实现方案
方案1:无捕获场景使用cdef函数替代(最简单)
如果排序逻辑不需要捕获外部变量,直接用cdef定义C级别的比较函数即可,性能和C++ lambda完全一致,示例代码如下:
# File: myfunc.pyx from libcpp.vector cimport vector from libcpp.algorithm cimport sort # 定义C级别的比较函数,参数、返回值匹配sort的要求 cdef bool compare_int(int a, int b) noexcept: return a < b cpdef myfunc(): cdef vector[int] v v.push_back(2) v.push_back(1) # 直接传入定义好的比较函数 sort(v.begin(), v.end(), compare_int) # 验证排序结果 print(list(v)) # 输出 [1,2]
方案2:有捕获场景使用Cython仿函数
如果需要捕获外部变量,可以定义Cython仿函数类存储捕获值,重载__call__方法实现比较逻辑:
from libcpp.vector cimport vector from libcpp.algorithm cimport sort cdef class IntComparator: # 存储捕获的外部变量 cdef int extra_offset def __init__(self, extra_offset): self.extra_offset = extra_offset # 重载调用方法实现比较逻辑 cdef bool __call__(self, int a, int b) noexcept: return a + self.extra_offset < b cpdef myfunc_with_capture(int offset): cdef vector[int] v v.push_back(2) v.push_back(1) # 实例化仿函数传入捕获值 cdef IntComparator comp = IntComparator(offset) sort(v.begin(), v.end(), comp) print(list(v))
方案3:封装C++原生lambda到独立头文件
如果习惯写C++ lambda,也可以把排序逻辑连带lambda一起封装到独立C++头文件,再通过Cython调用:
- 先编写C++头文件
sort_helpers.h:
#include <vector> #include <algorithm> inline void sort_vector_with_offset(std::vector<int>& v, int offset) { std::sort(v.begin(), v.end(), [offset](int a, int b) { return a + offset < b; }); }
- 再编写Cython代码调用封装好的函数:
from libcpp.vector cimport vector # 声明外部C++函数 cdef extern from "sort_helpers.h": void sort_vector_with_offset(vector[int]& v, int offset) cpdef myfunc_native_lambda(int offset): cdef vector[int] v v.push_back(2) v.push_back(1) sort_vector_with_offset(v, offset) print(list(v))
编译配置注意事项
setup.py需要显式开启C++17支持,示例配置如下:
from setuptools import setup from Cython.Build import cythonize setup( ext_modules = cythonize( "myfunc.pyx", language="c++", extra_compile_args=["-std=c++17"], extra_link_args=["-std=c++17"] ) )
内容的提问来源于stack exchange,提问作者Dan D
相关产品推荐
相关产品推荐

