PyO3 Class 详解 - 在 Python 中使用 Rust 类

PyO3 Class 详解 - 在 Python 中使用 Rust 类

PyO3 是一个强大的库,允许我们在 Rust 中定义类并在 Python 中使用。本文将详细介绍 PyO3 类的各种特性和使用方法。


📌 基本概念

PyO3 允许定义原生 Rust 类型并在 Python 中将其作为类公开。

定义类的基本语法

rust 复制代码
use pyo3::prelude::*;

#[pyclass]
struct MyClass {
    num: i32,
    debug_buffer: String,
}

🔧 构造函数

默认情况下,#[pyclass] 类型只能从 Rust 代码实例化。要使其可从 Python 实例化,需添加构造函数。

自定义构造函数

rust 复制代码
#[pymethods]
impl MyClass {
    #[new]
    fn new(num: i32) -> Self {
        MyClass { num }
    }
}

🎯 获取 Python 对象

当函数返回 #[pyclass] 类型时,会自动转换为 Python 对象。

使用 PyRef 和 PyRefMut

rust 复制代码
#[pymethods]
impl MyClass {
    // 只读访问
    fn get_debug_buffer(slf: PyRef<Self>) -> PyRef<String> {
        PyRef::map(slf, |this| &this.debug_buffer)
    }

    // 可变访问
    fn append_to_debug_buffer(mut slf: PyRefMut<Self>, value: String) -> PyResult<()> {
        slf.debug_buffer.push_str(&value);
        Ok(())
    }
}

💀 析构函数

rust 复制代码
#[pymethods]
impl MyClass {
    fn __del__(&self) {
        println!("MyClass is being deallocated");
    }
}

👪 继承

通过 extends 参数让 Rust 类继承其他 Python 类:

rust 复制代码
#[pyclass(extends=PyException)]
struct MyError {
    #[pyo3(get, set)]
    value: i32,
}

#[pymethods]
impl MyError {
    #[new]
    fn new(value: i32) -> (Self, PyException) {
        (MyError { value }, PyException::new_err("Error occurred"))
    }
}

⚙️ 配置参数

#[pyclass] 支持多种配置选项:

  • name: 指定 Python 中的类名
  • freelist: 优化内存分配
  • weakref: 启用弱引用支持
  • unsendable: 标记为非线程安全
  • module: 指定所属模块
rust 复制代码
#[pyclass(name = "MyCustomClass", freelist = 100, weakref, unsendable, module = "mymodule")]
struct MyClass {
    #[pyo3(get, set)]
    num: i32,
}

⚠️ 限制条件

无生命周期参数

  • Rust 生命周期是编译时概念,Python 运行时无法追踪
  • #[pyclass] 不能有生命周期参数

无泛型参数

  • Rust 泛型在每个使用点生成新实现
  • Python 需要单一实现与解释器集成
  • 解决方案:使用宏为每种具体类型生成类
rust 复制代码
macro_rules! create_interface {
    ($name: ident, $type: ty) => {
        #[pyclass]
        pub struct $name {
            inner: GenericClass<$type>,
        }
        #[pymethods]
        impl $name {
            #[new]
            pub fn new(data: $type) -> Self {
                Self {
                    inner: GenericClass { data },
                }
            }
        }
    };
}

create_interface!(IntClass, i64);
create_interface!(FloatClass, f64);

必须线程安全

  • Python 对象可在多线程间共享
  • #[pyclass] 必须实现 SendSync
  • 非线程安全类型可用 unsendable 标记

🔒 内部可变性

Borrow Checking

PyO3 在运行时进行借用检查,类似 std::cell::RefCell<T>

规则

  1. 任何时候只能有一个可变引用或多个不可变引用
  2. 引用不能超出所引用数据的生命周期
  3. Py<T>Bound<'py, T> 在运行时跟踪引用来确保这些规则

📝 字段属性

get/set 属性

rust 复制代码
#[pyclass]
struct MyClass {
    #[pyo3(get, set)]
    num: i32,  // 自动生成 getter 和 setter
    
    #[pyo3(get)]
    readonly_field: String,  // 只读字段
}

✅ 最佳实践

  1. 简单类型默认线程安全 :基础类型如 i32, String 等已满足要求
  2. 避免复杂内部可变性 :谨慎使用 Rc<RefCell<T>> 等非线程安全类型
  3. 合理使用宏:处理泛型限制时使用宏生成具体实现
  4. 明确编码声明:在 Python 文件中声明编码以避免国际化问题

PyO3 提供了一种优雅的方式来在 Rust 和 Python 之间建立互操作性,让我们能够充分利用两种语言的优势。通过掌握这些核心概念,我们可以在项目中有效地使用 PyO3 来构建高性能的 Python 扩展。

📚 更多 PyO3 相关内容,请参考官方文档

相关推荐
工程师老罗1 天前
Pytorch模型GPU训练
人工智能·pytorch·深度学习
香芋Yu1 天前
【深度学习教程——01_深度基石(Foundation)】03_计算图是什么?PyTorch动态图机制解密
人工智能·pytorch·深度学习
氵文大师1 天前
PyTorch 性能分析实战:像手术刀一样精准控制 Nsys Timeline(附自定义颜色教程)
人工智能·pytorch·python
林深现海1 天前
【刘二大人】PyTorch深度学习实践笔记 —— 第二集:线性模型(凝练版)
pytorch·笔记·深度学习
林深现海1 天前
【刘二大人】PyTorch深度学习实践笔记 —— 第三集:梯度下降(凝练版)
pytorch·笔记·深度学习
zhangfeng11331 天前
deepseek部署和训练的PyTorch CUDA Transformers Accelerate PEFT稳定版本呢推荐
人工智能·pytorch·python
查无此人byebye1 天前
从零解读CLIP核心源码:PyTorch实现版逐行解析
人工智能·pytorch·python·深度学习·机器学习·自然语言处理·音视频
鸿乃江边鸟1 天前
Spark Datafusion Comet 向量化Rust Native--创建Datafusion计划
rust·spark·native
咸甜适中1 天前
rust的docx-rs库,自定义docx模版批量分页生成一个docx文档(方便打印)(逐行注释)
rust·办公自动化·docx-rs
机器学习之心HML1 天前
GCN-TCN-Transformer回归模型 + SHAP 可解释性分析 Pytorch实现
pytorch·回归·transformer