Rust 开发系列PyO3:Rust与Python的联动编程(中)

news2025/1/23 15:12:52

第三节:对比C语言的Python原生扩展开发模式

C/c++编写Python扩展的方法,与Rust大致是相同的,如果不论语言本身的语法带来的繁琐的话,就单纯以开发步骤和模式来看,原生语言写扩展的步骤更为标准和简单。

大致来说,有如下三个步骤:

  1. 编写业务逻辑代码。一般来说,以C语言或者C++语言编写的业务逻辑代码,这个步骤可以完全不考虑Python和其他的内容,就是纯粹的C/C++内容。
  2. 写完业务逻辑之后,需要对代码进行包装和声明,用以在Python中暴露和进行交互调度。这一步在C/C++里面就比较繁琐了,我们在下页PPT中给大家做具体的介绍。
  3. 就是进行编译,这里不是用C/C++直接进行编译,而是使用Python的setup.py方法来编程为Python模块,注意,在windows上面,需要安装VC,使用cl.exe,而在Linux上一般用gcc。

下面我们来看看用C语言编写上面那个say hello 应该怎么做:

  1. 编写一个返回char* 类型的方法,C语言没有String类型,所以要字符串只能弄个字符指针或者字符数组,但是这中方式,恰恰是C/C++最被人诟病的地方之一:很容易造成悬垂指针。不过这不是我们今天的内容,先pass,暂且不提。

  2. 编写一个Python扩展的封装函数,如下所示:

static PyObject * sayhello_func(PyObject *self,PyOject *args){
    xxxx
    ……
}

简单解释一下,C/C++编写的Python扩展,需要返回C语言的Python对象,在Python的标准文档里面,声明了所有C语言与Python语言参数的转换标准,这个大家有兴趣自己去翻一下帮助文档就行。

另外,在这个封装的方法里面,还需要对Python调用时候传递的参数进行验证和转换,不过这几句话是模板化,只要你不传递复杂的对象,基本上直接套用模板就行。

  1. 需要编写一个静态的Python模块定义的数组,这个数组用来定义这个Python模块各项元数据,比如调用方法的对外暴露名称、执行业务功能的方法是哪个、参数类型是什么等等。

  2. 还要编写一个静态结构体,这个结构体是对外暴露的API帮助部分,在Python里面通过help方法可以获取到这些信息。

  3. 最后进行一个模块化封装,把上面的这些元数据、配置项和方法封装在一起,进行打包。

全部编写完成之后,你可以自定义一个main函数,来测试一下方法是否可用,确定没问题之后,就可以在Python中打包编译安装了:

一般打包都用Python的setuptools来做,编写好setup.py文件,设置各种编译项,然后直接用

python setup.py install

命令,就可以直接编译并且安装到你的Python环境中去了。

然后就可以用Python标准包的方式,进行导入和调用。

我们来对比一下C/C++和Rust对Python的扩展开发,可以得到如下结论:

  1. Rust编写的扩展比C/C++编写的扩展,从代码量、繁琐程度来看,都要优化很多,大量的工作都交给编译器和包管理器来做了。

  2. C/C++编写的扩展,结构上要比Rust更加严谨,但是显得太落后,有一种上古时代的历史厚重感……

  3. C/C++编写的代码,直接在Python里面进行编译和安装,似乎看起来要简单一些,不像裸奔的Rust那样,还要手动改名。

不过,下面我们要介绍的内容,就可以把这第三条直接拍死在岸上了。

第四节:PyO3的官方脚手架maturin

所谓的脚手架,就是指在建筑施工的时候,为了保证各施工过程顺利进行而搭设的工作平台,施工完成之后会被拆卸掉的东西。

maturin这个PyO3的官方脚手架,就是用来辅助我们编写Rust的Python扩展的一个辅助平台。

maturin这个工具,就是用Rust写的一个Python扩展工具包,我们直接可以通过PIP进行安装即可。

然后利用这个工具包,我们可以很方便的构筑一个PyO3工程,并且能够实现简便的编译、打包和安装过程。

做为脚手架,最大好处就是简单方便,只需要一个命令,就可以生成所有的配置项,包括示例代码:

写完所有的功能代码之后,也只需要一个命令,就可以一次性自动完成编译、安装全过程:

安装好的包,就已经是标准的Python站点包了,不但可以在Python环境中导入和调用,也可以通过pip进行管理:

下面是maturin的一些相关参数:

 

这里需要说明的是,build这个参数,需要在后面加上-f 参数,否则在windows上面build的出错,其他的参数,例如develop则不会出差,所以有些疑惑。(有文章提到是build的一个bug,未能确定)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/397040.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT入门Item Views之QTreeView

目录 一、QTreeView界面相关 1、布局介绍 二、基本属性功能 1、设置单元格不能编辑 2、一次选中一个item 3、去掉鼠标移动到单元格上的虚线框 4、最后一列自适应 三、代码展示 1、创建模型,导入模型 2、 右键菜单栏 3、双…

深度学习模型训练工作汇报(3.8)

进行数据的初始整理的准备 主要是进行伪序列字典的设置,以及训练数据集的准备。 期间需要的一些问题包括在读取文件信息的时候,需要跳过文件的第一行或者前两行,如果使用循环判断的话,会多进行n次的运算,这是不划算的…

003+limou+HTML——(3)HTML列表

000、前言 列表是网页常见的一种数据排列方式,在HTMl中列表一共有三种:有序列表、无序列表、定义列表(另外“目录列表dir”和“菜单列表menu”已经在HTML5中被废除了,现在都是使用无序列表ul来替代) 001、有序列表&a…

C/C++指针与数组(一)

预备知识 1、数据的存储 2、基本内建类型 1)类型的大小 C offers a flexible standard with some guaranteed minimum sizes, which it takes from C: A short integer is at least 16 bits wide.An int integer is at least as big as short.A long integer is a…

Spring Cloud学习笔记:基础知识

这是本人学习的总结,主要学习资料如下 马士兵教育 目录1、Spring Cloud 简介2、Eureka3、建立Spring Cloud项目3.1、启动Server3.1.1、dependency3.1.2、配置文件3.1.3、Server端启动代码3.2、启动Client3.2.1、dependency3.2.2、配置文件3.3.3、Client端启动代码3…

Go之入门(特性、变量、常量、数据类型)

一、Go语言特性 语法简单并发性。Go语言引入了协程goroutine,实现了并发编程内存分配。Go语言为了解决高并发下内存的分配和管理,选择了tcmalloc进行内存分配(为了并发设计的高性能内存分配组件,使用cache为当前线程提供无锁分配…

电脑自动重启是什么原因?详细解说

案例:电脑自动重启是什么原因? “一台用了一年的电脑,最近使用,每天都会一两次莫名其妙自动重启,看了电脑错误日志,看不懂什么意思,一直找不到答案。有没有高手知道怎么解决这个问题的。” 当…

仿写简单IOC

目录 TestController类: UserService类: 核心代码SpringIOC: Autowired和Component注解 SpringIOCTest 类 ​编辑 总结: TestController类: Component public class TestController {Autowiredprivate UserService userService;public void test…

RocketMQ如何测试

RocketMQ如何测试MQ简介RocketMQRocketMQ测试点MQ简介 MQ:Message Queue,即消息队列,是一种应用程序之间的消息通信,简单理解就是A服务不断的往队列里发布信息,另一服务B从队列中读取消息并执行处理,消息发…

同步、异步ETL架构的比较

背景介绍: 数据的抽取,转换和加载 (ETL, Extract, Transform, Load) 是构建数据仓库过程中最复杂也是至 关重要的一个步骤,我们通常用两种办法来处理 ETL 流程: 一种是异步(Asynchronous) ETL 方式, 也称为文本文件(Flat file)方式。 另外…

华为云平台架构名词解释

名词解释 网络设备 ISW(外网接入交换机):出口交换机,常用于和外网建立静态/BGP路由互联 CSW (内网接入交换机):专线接入(用户内网骨干)交换机,用户自有网络…

一场以数字技术深度影响和改造传统实业的新风口,正在开启

当数字经济的浪潮开始上演,一场以数字技术深度影响和改造传统实业的新风口,正在开启。对于诸多在互联网时代看似业已走入死胡同的物种来讲,可以说是打开了新的天窗。对于金融科技来讲,同样如此。以往,谈及金融科技&…

蓝桥杯-左移右移(2022国赛)

蓝桥杯-左移右移1、问题描述2、解题思路与代码实现2.1 方法一:使用LinkedList双向链表实现(50%)2.2 方法二:使用HashMap左右临界值实现(100%)1、问题描述 小蓝有一个长度为 N 的数组, 初始时从左到右依次是 1,2,3,…N 。 之后小蓝对这个数组进行了 M 次操…

TX2配置RealSense D455相机SDK和ros驱动

TX2配置RealSense D455相机SDK和ros驱动1 SDK安装2 RealSense-ros安装3 bug及解决3.1 realsense-viewer显示usb2.13.2 Could not found ddynamic_reconfigure折腾了两天终于把realsense的驱动装好了,尝试了命令安装,源码安装,前前后后搞了三遍…

12.并发编程

1.并发并发:逻辑流在时间时重叠构造并发程序:进程:每个逻辑控制流是一个进程,由内核调度和维护进程有独立的虚拟地址空间,想要通信,控制流必须使用某种显式的进程间通信机制(IPC)I/O多路复用:程…

Linux - 第6节 - 动态库和静态库

1.静态库与动态库概念 静态库(.a):程序在编译链接的时候把库的代码拷贝到可执行文件中。程序运行的时候将不再需要静态库。动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用…

【javaEE初阶】第三节.多线程 (进阶篇 ) 死锁

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、"死锁"出现的典型场景二、产生 "死锁" 的必要条件 三、解决 "死锁" 问题的办法 总结前言 今天对于多线程进阶的学习&#…

【MapGIS精品教程】007:MapGIS投影变换案例教程

MapGIS投影变换,包括创建坐标系、定义投影、单点投影、类投影、批量投影。 文章目录 一、创建坐标系1. 创建高斯平面坐标系2. 创建阿尔伯斯投影二、定义投影三、投影变换1. 单点投影2. 类投影3. 批量投影一、创建坐标系 在MagGIS数据库中,有个空间参考系的文件夹,内置了常见…

【tensorflow onnx】TensorFlow2导出ONNX及模型可视化教程

文章目录1 背景介绍2 实验环境3 tf2onnx工具介绍4 代码实操4.1 TensorFlow2与ONNX模型导出4.2 ONNX正确性验证4.3 TensorFlow2与ONNX的一致性检查4.4 多输入的情况4.5 设定输入/输出节点5 ONNX模型可视化6 ir_version和opset_version修改7 ONNX输入输出维度修改8 致谢原文来自于…

【教学典型案例】18.开门小例子理解面向对象

目录一:背景介绍业务场景:业务分析:二:实现思路1、面向过程:2、面向对象(抽象、封装、继承、多态)3、面向对象(抽象、封装、继承、多态、反射)三:实现过程1、…