创建一个rust写的python库[signatures和错误处理]

照例先创建初始话选pyo3

复制代码
maturin init

修改src/lib.rs

rust 复制代码
use pyo3::prelude::*;
use pyo3::types::{PyDict, PyTuple};
use pyo3::exceptions::PyValueError;
use pyo3::exceptions::PyOSError;
use std::num::ParseIntError;
use std::fmt;

// 定义一个类
#[pyclass]
struct MyClass {
    num: i32,
}

// 实现类方法
#[pymethods] 
impl MyClass {
    #[new]
    #[pyo3(signature = (num=-1))]
    fn new(num:i32) -> Self {
        MyClass { num }
    }
    #[pyo3(signature = (num=10,*py_args,name="Hello",**py_kwargs))]
    fn method(
        &mut self,
        num: i32,
        py_args: &Bound<'_, PyTuple>,// 接受任意个python位置参数(positional argument)
        name: &str,
        py_kwargs: Option<&Bound<'_, PyDict>>,// 接受任意个python关键字参数(keyword argument)
    ) -> String {
        let num_before = self.num;
        self.num = num;
        format!(
            "num={} (was previously={}), py_args={:?}, name={}, py_kwargs={:?} ",
            num, num_before, py_args, name, py_kwargs,
        )
    }
    fn make_change(&mut self, num: i32) -> PyResult<String> {
        self.num = num;
        Ok(format!("num={}", self.num))
    }
}

#[pyfunction]
// 用new_err创建一个PyErr
fn check_positive(x: i32) -> PyResult<()> {
    if x < 0 {
        Err(PyValueError::new_err("x is negative"))
    } else {
        Ok(())
    }
}

#[pyfunction]
fn parse_int(x: &str) -> Result<usize, ParseIntError> {
    x.parse()
}

#[pyfunction]
fn parse_int2(x: &str) -> PyResult<usize> {
    let x = x.parse()?;
    Ok(x)
}
// 自定义IO错误CustomIOError
// 实现标准库的Error trait
// 实现Display trait
// 实现From trait,定义如何将自定义CustomIOError转换成PyO3的PyErr
#[derive(Debug)]
struct CustomIOError;
impl std::error::Error for CustomIOError {}
impl fmt::Display for CustomIOError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Oh no!")
    }
}
impl std::convert::From<CustomIOError> for PyErr {
    fn from(err: CustomIOError) -> PyErr {
        PyOSError::new_err(err.to_string())
    }
}


#[pyfunction]
fn parse_int3(x: &str) -> Result<usize,CustomIOError> {
    match x.parse() {
        Ok(parsed) => Ok(parsed),
        Err(_) => Err(CustomIOError),
    }
    
}
/// A Python module implemented in Rust.
#[pymodule]
mod my_extension_sign_err {
    use pyo3::prelude::*;
    use pyo3::types::{PyDict, PyTuple}; //python的字典格
 
    #[pymodule_export]
    use super::MyClass;
    
    #[pymodule_export]
    use super::check_positive;

    #[pymodule_export]
    use super::parse_int;

    #[pymodule_export]
    use super::parse_int2;

    #[pymodule_export]
    use super::parse_int3;

    #[pyfunction]
    #[pyo3(signature = (**kwds))]//接受任意个数参数
    fn num_kwds(kwds: Option<&Bound<'_, PyDict>>) -> usize {
        kwds.map_or(0, |dict| dict.len())
    }
}

这段代码定义了一个名为 my_extension_sign_err 的 Python 模块,它包含一个类 MyClass 和多个函数(如 check_positiveparse_int)。代码展示了 PyO3 的核心功能:

  • 使用 #[pyclass]#[pymethods] 定义 Python 类。
  • 通过 #[pyfunction] 导出 Python 函数。
  • 处理错误和异常,包括自定义错误转换。
  • 支持复杂的函数签名(如位置参数和关键字参数)。

先编译安装一下

rust 复制代码
maturin develop

再写个脚本测试一下

python 复制代码
import my_extension_sign_err

# 传入多个任意参数
print(my_extension_sign_err.num_kwds(a=1, b=2, c=3,d='ood'))

# 使用类方法
myclass = my_extension_sign_err.MyClass()
print(myclass.method(1,[2,3],'ood',a=1,b=2,c=3))
print(myclass.make_change(13))
print(myclass.method(1,[2,3],'ood',a=1,b=2,c=3))

# 使用异常处理,自定义PyErr
try:
    res = my_extension_sign_err.check_positive(12)
    print(res)
    res = my_extension_sign_err.check_positive(-12)
    print(res)
except Exception as e:
    print(e)

# 使用异常处理,ParseIntError    
try:
    res = my_extension_sign_err.parse_int("11")
    print(res)
    res = my_extension_sign_err.parse_int("bar1")
    print(res)
except Exception as e:
    print(e)

# 使用异常处理,PyResult包装
try:
    res = my_extension_sign_err.parse_int2("12")
    print(res)
    res = my_extension_sign_err.parse_int2("bar2")
    print(res)
except Exception as e:
    print(e)

# 使用异常处理,使用自定义CustomIOError
try:
    res = my_extension_sign_err.parse_int3("13")
    print(res)
    res = my_extension_sign_err.parse_int3("bar3")
    print(res)
except Exception as e:
    print(e)

执行结果

相关推荐
喜欢喝果茶.3 分钟前
QOverload<参数列表>::of(&函数名)信号槽
开发语言·qt
亓才孓4 分钟前
[Class类的应用]反射的理解
开发语言·python
努力学编程呀(๑•ี_เ•ี๑)4 分钟前
【在 IntelliJ IDEA 中切换项目 JDK 版本】
java·开发语言·intellij-idea
小镇敲码人13 分钟前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
island131426 分钟前
CANN GE(图引擎)深度解析:计算图优化管线、内存静态规划与异构任务的 Stream 调度机制
开发语言·人工智能·深度学习·神经网络
坚持就完事了30 分钟前
Java中的集合
java·开发语言
摘星编程33 分钟前
深入理解CANN ops-nn BatchNormalization算子:训练加速的关键技术
python
魔芋红茶34 分钟前
Python 项目版本控制
开发语言·python
lili-felicity41 分钟前
CANN批处理优化技巧:从动态批处理到流水线并行
人工智能·python
一个有梦有戏的人43 分钟前
Python3基础:进阶基础,筑牢编程底层能力
后端·python