首页 > 编程语言 >如何选择Python与C++之间的胶水:Boost.Python,Cython,pybind11,SWIG

如何选择Python与C++之间的胶水:Boost.Python,Cython,pybind11,SWIG

时间:2023-02-27 19:22:56浏览次数:38  
标签:Cython 封装 Python SWIG C++ pybind11 Boost

Python作为一门胶水语言,它与C/C++之间的兼容性(Interoperability)我认为是它相比其他动态语言脱颖而出的最大原因。Python原生支持的是与C语言的接口,Python的发行版自带有Python.h头文件,里面提供了在C中调用Python和反过来在Python中调用C的接口定义。但是C++就不一样了,虽然C++ ⇔ C ⇔ Python的通道是可行的,但是想要完整兼容C++的特性的话需要很多额外的重复代码(boilerplate)。因此相应针对Python/C++绑定的库也就应运而生了,我所了解的库主要有四个:Boost.Python,Cython,pybind11,SWIG。

总的来说,Boost.Python和pybind11主要用于给现有C++代码提供Python绑定,并且不用学习新的语法;SWIG提供一个给C++代码编写多种语言绑定的框架,它本质上是一种代码生成器,基于SWIG自定义的语法;Cython则是基于Python的C/C++代码封装器,其本质也是代码生成器,但是Cython的语法是Python的超集,也就是说Python的代码可以零成本移植到Cython中。

Boost.Python是一个Boost框架中封装C++代码的工具,通过宏定义和元编程来简化Python的API调用,消灭bolierplate。Boost.Python还提供对Numpy底层API的封装,因此适用性很强,能满足Python绑定的绝大多数需求。而pybind11则是受Boost.Python启发的一套类似的API,其目标是提供Header-only的易用的Python接口。由于pybind11脱胎于Boost,因此它们的接口非常相似,

Boost.Python/pybind11 vs Cython
这两者的选用其实差别非常大,因为他们的代码逻辑都是不同的。而具体选择哪个库就纯粹是根据需求出发了。他们的区别如下(以下pybind11同时也代表了Boost.Python)
pybind11基于C++,更适合C++工程师。Cython则是基于Python,写习惯的Python的人上手更快,并且能同时方便地兼容Python和C++。
Cython相比pybind11的环境配置更加简单,用户只需通过pip安装Cython就可以利用Cython的功能了,也无需配置路径。
Cython封装C++类会比Boost.Python更加繁杂,你需要先定义C++类,再封装成Python类。相当于Cython还多一步翻译头文件的工作。
Cython支持模板(虽然是阉割版本)!这是Cython独家的一个killer特性,不过是与第3点相关联的。如果你已经翻译好了现有的模板代码,那么用户就可以用Python的语法来自行展开模板了!pybind11需要在编译的时候实例化模板,因此一般只封装常用的实例,或者穷举所有实例化可能(这会导致生成的封装库尺寸爆炸)
pybind11封装重载函数比Cython要方便太多!Cython封装重载函数的话一般需要定义大量的可选参数和类型判断。
Cython封装继承类就更加麻烦了,不仅要处理方法重载,还要复制继承关系,十分繁复。
Cython无法利用上C++的宏定义,这对支持条件编译非常不利,很多时候还需要自己利用Cython的条件语句翻译一套条件编译的逻辑。
Cython似乎在封装上比pybind11性能好,参见pybind11#1227和pybind#2005。如果你的代码需要经常调用封装后的函数,那么选择Cython性能更好。

SWIG
SWIG是个很神奇的东西,他能够将C++代码封装成Python/C#/Java/Ruby等多种语言,但是也正因为这个灵活性,它对C++的高级特性的支持就比较辣鸡了。在CGAL官方的绑定库中可以看到有不少代码需要针对Python和Java打补丁,因此如果没有多语言的需求的话SWIG应该是下下策了。这应该也是SWIG一直没啥发展的原因吧~

简而言之,选择Cython的情况有以下几种需要保留模板参数,让用户可以自行选择用什么类型展开,或者目标用户有继续使用和拓展C++ API的需求有大量的封装函数调用时,Cython的性能最好绑定的对象是C语言写的,那么用Cython封装会更快而选择SWIG只有在你需要同时生成多个语言的绑定的时候推荐使用,其他情况无脑选择pybind11即可。

网友评价:
用过cython和pybind11,就这两者而言,pybind11的体验超好,推荐!
Tensorflow已经从SWIG切到pybind11了
个人比较喜欢/偏向于pybind11,有以下几个原因1. 灵活性:pybind11本质上还是在C API外面包了一层C++(或者说利用C++的元编程能力批量产生binding)所以可定制性很好,尤其是面向我这种有非主流需求的用户。2. 抽象能力:cython这种Python的补丁抽象能力没有完整的C++好,对于一个倾向于只让Python成为傻瓜式接口的人,我更希望能够同时在C++层面有丰富的抽象来方便developer。3. 生态:pybind11现在有很多基于它的生态,例如xtensor,Python/C++里最好的多维数组没有之一。然后还有pythran这个transpiler,可以把Python的prototype转到C++,一定程度上减轻编写C++的蛋疼点。PS. 我觉得有了pythran以后cython已经没有任何优势了。

cython就算了,大清都忘了swig自动化程度特别高,include头文件即可,封装做的好,而且可以同时产出lua等接口pybind11灵活性更高,手撸接口比较方便如果需要产出多种脚本语言的binding、需要导出的接口比较多、或者希望自动化完成尽量使用swig,否则请选择pybind11

我的结论就是使用pybind11,

标签:Cython,封装,Python,SWIG,C++,pybind11,Boost
From: https://www.cnblogs.com/andy0816/p/17161559.html

相关文章

  • ChatGPT: python3 查找在列表1中而不再列表2的项目
    A:f1_urls=['a','b']f2_urls=['a','c']python3中获取存在于f1_urls而不在f2_urls的项目Q:f1_urls=['a','b']f2_urls=['a','c']#将列表转换为集......
  • python用turtle画出给定图片的图像
    python用turtle画出给定图片的图像、校徽等复杂图像都可以需要:1.要画的图片2.安装好cv和turtle打开python文件,把想画的图片放到和py文件同目录,代码中默认图片名字为1.xxxxx......
  • python算法基础
    一、简介定义和特征定义:算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定......
  • python通过snmp获取交换机端口状态
    frompysnmp.entity.rfc3413.onelinerimportcmdgenclassNumberStatus:def__int__(self,host):self.host=hostdefwalk(self,dswitch,comm......
  • python -- PyQt5(designer)安装详细教程
    摘自:https://blog.csdn.net/weixin_64338372/article/details/128111818先展示一下安装好后的效果如下:  PyQt5基本教程大全​​​​​​​http://t.csdn.cn/L50jl......
  • 【Python】判断字符串输入合法化
    Python判断字符串输入合法化​​只包含数字​​​​包含数字​​​​只包含中文​​​​包含中文​​​​只包含字母​​​​包含字母​​只包含数字判断字符串是否只包含数......
  • 【Python】a[1:-1]、a[-1]、a[:-1]、a[::-1]、a[n::-1]等操作的区别
    a[1:-1]a[n:-n]作用是去除前n个元素和末n个元素>>>a=(1,2,3,4,5)>>>a[1:-1](2,3,4)>>>a=(1,2,3,4,5)>>>a[2:-2](3,)a[-1]a[-n]作用是取倒数第n个元素>>>a=(1,2,3,4,5......
  • 【Python】ImportError: No module named ‘google‘最全解决方法
    跑程序遇到了这个问题,改了好久才解决,由于每个人实际情况不同,现列出各种解决办法:我的环境:pycharmpython3.7首先确定是否装了google这个包,如果依然报错再找问题1这是我成......
  • 【Python】 basemap 报错‘module‘ object is not callable
    报错:Traceback(mostrecentcalllast):File"/Users/ddd/Desktop/map_01.py",line5,in<module>m=Basemap()#使用Basemap()创建一个地图File"/Users/ddd......
  • 使用python暴力破解WiFi密码
    当我们遇到没有网络,有WiFi但不知道密码的情况或者是练习python时可以使用这几行简单的代码去破解wifi密码准备工作一:python环境二:pycharm/其他可以运行python代码平台......