当前位置: 首页 > news >正文

Python与Rust混合编程实战:发挥两种语言的优势

Python与Rust混合编程实战:发挥两种语言的优势

后端转 Rust 的萌新,ID "第一程序员"——名字大,人很菜(暂时)。正在跟所有权和生命周期死磕,日常记录 Rust 学习路上的踩坑经验和"啊哈时刻",代码片段保证能跑。保持学习,保持输出。欢迎大佬们轻喷,也欢迎同好一起进步。

前言

最近在学习 Rust 的过程中,我一直在思考如何将 Rust 与 Python 结合起来,发挥两种语言的优势。Python 以其简洁易学、生态丰富而闻名,而 Rust 则以其内存安全、高性能而受到青睐。如果能够将两者结合起来,岂不是能创造出既开发效率高又运行性能好的应用?今天就来分享一下我的 Python 与 Rust 混合编程实践,希望能帮到和我一样的萌新们。

为什么要混合使用 Python 和 Rust?

Python 的优势

  • 开发效率高:Python 语法简洁,代码量少,开发速度快
  • 生态丰富:拥有大量的第三方库,几乎可以解决任何问题
  • 易学易用:学习曲线平缓,适合快速原型开发
  • 数据科学和机器学习:在数据处理、分析和机器学习领域有丰富的工具和库

Rust 的优势

  • 性能优异:编译为原生代码,执行速度快
  • 内存安全:所有权系统和借用检查器保证内存安全
  • 并发安全:无数据竞争的并发编程
  • 系统级编程:可以直接操作硬件和系统资源
  • 跨平台:一次编译,多处运行

混合编程的优势

  • 性能关键部分用 Rust:将计算密集型任务用 Rust 实现,提高性能
  • 业务逻辑用 Python:利用 Python 的开发效率和丰富的生态
  • 渐进式迁移:可以逐步将 Python 代码迁移到 Rust,而不是一次性重写
  • 充分利用现有代码:可以在不放弃现有 Python 代码的情况下,逐步引入 Rust

Python 与 Rust 交互的方式

1. 使用 PyO3

PyO3 是一个 Rust 库,用于创建 Python 扩展模块。它允许你在 Rust 中定义 Python 可调用的函数和类型。

安装 PyO3

# 在 Cargo.toml 中添加 [dependencies] pyo3 = { version = "0.18", features = ["extension-module"] } [lib] crate-type = ["cdylib"]

示例:创建一个简单的 Rust 扩展

use pyo3::prelude::*; /// 计算斐波那契数列 #[pyfunction] fn fibonacci(n: u64) -> u64 { match n { 0 => 0, 1 => 1, _ => fibonacci(n - 1) + fibonacci(n - 2), } } /// 一个简单的加法函数 #[pyfunction] fna add(a: i32, b: i32) -> i32 { a + b } /// 定义 Python 模块 #[pymodule] fn rust_extension(_py: Python, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(fibonacci, m)?)?; m.add_function(wrap_pyfunction!(add, m)?)?; Ok(() ) }

构建和使用

# 构建 cargo build --release # 将生成的 .so 文件重命名为 Python 可导入的名称 cp target/release/librust_extension.so rust_extension.so # 在 Python 中使用 import rust_extension print(rust_extension.add(1, 2)) # 输出: 3 print(rust_extension.fibonacci(10)) # 输出: 55

2. 使用 ctypes

ctypes 是 Python 的标准库,用于调用 C 函数。由于 Rust 可以编译为 C 兼容的库,我们可以使用 ctypes 来调用 Rust 函数。

示例

// src/lib.rs #[no_mangle] pub extern "C" fn add(a: i32, b: i32) -> i32 { a + b }
# Cargo.toml [lib] crate-type = ["cdylib"]
# 使用 ctypes 调用 import ctypes # 加载 Rust 库 lib = ctypes.CDLL('./target/release/libmy_lib.so') # 定义函数签名 lib.add.argtypes = [ctypes.c_int, ctypes.c_int] lib.add.restype = ctypes.c_int # 调用函数 result = lib.add(1, 2) print(result) # 输出: 3

3. 使用 Rust-cpython

Rust-cpython 是另一个用于 Python 和 Rust 交互的库,提供了类似于 PyO3 的功能。

4. 使用 subprocess

对于简单的场景,我们可以使用 subprocess 模块在 Python 中调用 Rust 可执行文件。

示例

// src/main.rs fn main() { let args: Vec<String> = std::env::args().collect(); if args.len() == 3 { let a: i32 = args[1].parse().unwrap(); let b: i32 = args[2].parse().unwrap(); println!("{}", a + b); } }
# 使用 subprocess 调用 import subprocess result = subprocess.run(['./target/release/add', '1', '2'], capture_output=True, text=True) print(result.stdout.strip()) # 输出: 3

实战案例:高性能数据处理

需求分析

假设我们需要处理一个大型 CSV 文件,计算其中某一列的平均值。对于大型文件,Python 的处理速度可能会比较慢,我们可以使用 Rust 来加速这个过程。

实现步骤

  1. 创建 Rust 库:实现 CSV 文件的读取和计算
  2. 创建 Python 接口:使用 PyO3 包装 Rust 函数
  3. 在 Python 中使用:调用 Rust 函数处理数据

Rust 部分

// src/lib.rs use pyo3::prelude::*; use csv::ReaderBuilder; use std::fs::File; #[pyfunction] pub fn calculate_average(file_path: &str, column_index: usize) -> PyResult<f64> { let file = File::open(file_path).map_err(|e| PyErr::new::<pyo3::exceptions::PyIOError, _>(e.to_string()))?; let mut rdr = ReaderBuilder::new().has_headers(true).from_reader(file); let mut sum = 0.0; let mut count = 0; for result in rdr.records() { let record = result.map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))?; if let Some(value) = record.get(column_index) { if let Ok(num) = value.parse::<f64>() { sum += num; count += 1; } } } if count == 0 { return Err(PyErr::new::<pyo3::exceptions::PyValueError, _>("No valid numbers found in column")); } Ok(sum / count as f64) } #[pymodule] fn csv_processor(_py: Python, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(calculate_average, m)?)?; Ok(() ) }
# Cargo.toml [package] name = "csv-processor" version = "0.1.0" edition = "2021" [dependencies] pyo3 = { version = "0.18", features = ["extension-module"] } csv = "1.2" [lib] crate-type = ["cdylib"]

Python 部分

import csv_processor # 生成测试数据 import csv import random with open('test_data.csv', 'w', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'value']) for i in range(1000000): writer.writerow([i, random.random() * 100]) # 使用 Rust 函数计算平均值 import time start_time = time.time() average = csv_processor.calculate_average('test_data.csv', 1) end_time = time.time() print(f"平均值: {average}") print(f"处理时间: {end_time - start_time:.2f} 秒") # 与纯 Python 实现比较 start_time = time.time() sum_val = 0 count = 0 with open('test_data.csv', 'r') as f: reader = csv.reader(f) next(reader) # 跳过表头 for row in reader: sum_val += float(row[1]) count += 1 average_py = sum_val / count end_time = time.time() print(f"Python 平均值: {average_py}") print(f"Python 处理时间: {end_time - start_time:.2f} 秒")

性能对比

在处理 100 万行数据时,Rust 实现的处理速度通常比纯 Python 实现快 5-10 倍,具体取决于硬件和数据特性。

实战案例:Web 应用后端

需求分析

假设我们需要构建一个 Web 应用后端,其中包含一些计算密集型的任务。我们可以使用 Python 的 Flask 框架处理 HTTP 请求,而将计算密集型任务委托给 Rust 处理。

实现步骤

  1. 创建 Rust 库:实现计算密集型任务
  2. 创建 Python 接口:使用 PyO3 包装 Rust 函数
  3. 创建 Flask 应用:处理 HTTP 请求并调用 Rust 函数

Rust 部分

// src/lib.rs use pyo3::prelude::*; #[pyfunction] pub fn compute_prime_numbers(limit: u64) -> PyResult<Vec<u64>> { let mut primes = Vec::new(); for num in 2..=limit { if is_prime(num) { primes.push(num); } } Ok(primes) } fn is_prime(n: u64) -> bool { if n <= 1 { return false; } for i in 2..=(n as f64).sqrt() as u64 { if n % i == 0 { return false; } } true } #[pymodule] fn prime_calculator(_py: Python, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(compute_prime_numbers, m)?)?; Ok(() ) }

Python 部分

from flask import Flask, request, jsonify import prime_calculator app = Flask(__name__) @app.route('/api/primes', methods=['GET']) def get_primes(): limit = request.args.get('limit', type=int, default=100) try: primes = prime_calculator.compute_prime_numbers(limit) return jsonify({ 'limit': limit, 'primes': primes, 'count': len(primes) }) except Exception as e: return jsonify({'error': str(e)}), 500 if __name__ == '__main__': app.run(debug=True)

常见问题与解决方案

1. 类型转换

问题:Python 和 Rust 的类型系统不同,需要进行类型转换。

解决方案:PyO3 提供了自动类型转换,对于复杂类型,可以使用IntoPyFromPyObjecttraits 进行自定义转换。

2. 内存管理

问题:Python 使用垃圾回收,而 Rust 使用所有权系统,需要注意内存管理。

解决方案:使用 PyO3 提供的Py类型和GILGuard来管理 Python 对象的生命周期。

3. 错误处理

问题:Python 和 Rust 的错误处理方式不同。

解决方案:使用 PyO3 的PyResultPyErr来在 Rust 和 Python 之间传递错误。

4. 构建和部署

问题:混合 Python 和 Rust 代码的构建和部署比较复杂。

解决方案:使用maturin工具来简化构建和部署过程。

# 安装 maturin pip install maturin # 构建和安装 maturin develop

最佳实践

  1. 明确职责划分:将计算密集型任务交给 Rust,将业务逻辑和胶水代码交给 Python。

  2. 保持接口简单:设计清晰、简单的接口,减少 Python 和 Rust 之间的数据传输开销。

  3. 使用成熟的库:优先使用 PyO3 这样成熟的库来处理 Python 和 Rust 之间的交互。

  4. 性能测试:在混合编程之前,先进行性能测试,确保 Rust 实现确实能带来性能提升。

  5. 文档和注释:为 Rust 和 Python 代码都添加详细的文档和注释,方便维护。

  6. 版本兼容性:注意 Python 和 Rust 版本的兼容性,避免因版本问题导致的错误。

总结

Python 与 Rust 的混合编程是一种强大的开发方式,它结合了 Python 的开发效率和 Rust 的性能优势。通过 PyO3、ctypes 等工具,我们可以轻松实现 Python 和 Rust 之间的交互,为我们的应用带来更好的性能和开发体验。

虽然混合编程会增加一些复杂性,但对于性能要求较高的应用来说,这种复杂性是值得的。随着 Rust 生态的不断发展,Python 与 Rust 的交互会变得越来越简单和高效。

保持学习,保持输出!今天的 Python 与 Rust 混合编程实战文章就到这里,希望对大家有所帮助。欢迎在评论区分享你的经验和问题,我们一起进步!

参考资料

  • PyO3 文档
  • Rust 官方文档
  • Python ctypes 文档
  • maturin 文档

后端转 Rust 的萌新,ID "第一程序员"——名字大,人很菜(暂时)。正在跟所有权和生命周期死磕,日常记录 Rust 学习路上的踩坑经验和"啊哈时刻",代码片段保证能跑。保持学习,保持输出。欢迎大佬们轻喷,也欢迎同好一起进步。

http://www.jsqmd.com/news/608465/

相关文章:

  • Filament Shield 用户角色分配:5种高效的用户权限管理方法
  • 千问3.5-2B模型量化效果:INT4/FP16精度对比与RTX 4090 D推理速度实测
  • 抖音视频解析下载助手,支持多视频批量解析下载,操作简单高效无水印下载软件
  • JavaWeb 笔记 05 (50 - 72)
  • 验证码背后的黑科技:浏览器如何判断你是真人还是机器人?
  • 怎么批量压缩图片?4个方法快速批量压缩上百张图片
  • BiliBili-UWP:实现90%功能覆盖的Windows原生B站客户端方案
  • Windows电脑变身私有云!VMware17+黑群晖7.2保姆级配置指南(含远程访问方案)
  • 零代码搞定重复工作:用TinyTask实现Windows自动化操作全攻略
  • 仅剩127天!Python 3.15将默认启用AOT:2026兼容配置清单已同步至PSF安全白名单(附审计编号PSF-AOT-2026-041)
  • 别再只会用SIFT了!OpenCV实战:用ORB+BfMatcher搞定图像特征匹配(附Python代码)
  • WPF新手村教程(七)—— 终章(MVVM架构初见杀)疤
  • Qwen2.5-72B-Instruct-GPTQ-Int4效果展示:实时翻译+文化适配+语气风格保留能力
  • Web开发方向之前端技术框架
  • 一文搞懂 Spring Cloud:从入门到实战的微服务全景指南(建议收藏)盼
  • Onekey Steam Depot清单智能获取与高效管理指南
  • 比迪丽AI绘画安全部署:内网环境下的模型应用方案
  • 别再只盯着二维码了!用Aruco码和ROS给你的机器人一双‘慧眼’,实现精准定位
  • 2026年串联谐振试验装置厂家推荐:调频串联谐振试验装置/调感串联谐振试验装置/变频串联谐振试验装置/TPXB-W型无局放变频串联谐振试验装置/TPXB系列串联谐振试验装置专业选型指南 - 品牌推荐官
  • LLC谐振变换器设计避坑指南:Mathcad公式推导中的5个易错点
  • 【架构设计】去中心化边缘网络:如何用不稳定节点构建高可用采集集群?
  • 如何高效解决vscode-mermaid-preview图表渲染问题:5个实用技巧与完整指南
  • Mcool3360 是一款“没有界面,只有音乐”透明音乐播放器
  • 从SEO到GEO的变革:2026年企业“AI获客”新基建布局 - 品牌2025
  • 别再对着黑乎乎的标签图发愁了!手把手教你给农业大棚遥感数据集上色(附Python代码)
  • s2-pro镜像优势解析:单页工具设计 vs 多轮聊天页的效率对比
  • Kubernetes与机器学习训练作业管理
  • 收藏!金三银四必看|某鹅大模型算法岗三轮面试复盘(含RAG/微调/代码实战)
  • Web开发方向之人工智能核心技术线
  • 2026年4月行业内除尘器制造厂,沸石转轮+CO/沸石转轮/除尘器/活性炭箱/催化燃烧/RTO,除尘器厂商实力 - 品牌推荐师