创建一个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)

执行结果

相关推荐
Testopia2 分钟前
走一遍 AI 学习之路 —— AI实例系列说明
开发语言·人工智能·python
Tony Bai4 分钟前
【分布式系统】11 理论的试金石:用 Go 从零实现一个迷你 Raft 共识
开发语言·后端·golang
机 _ 长5 分钟前
YOLO26 改进 | 训练策略 | 知识蒸馏 (Response + Feature + Relation)
python·深度学习·yolo·目标检测·机器学习·计算机视觉
Beginner x_u5 分钟前
JavaScript 原型、原型链与原型继承的核心机制解析
开发语言·javascript·原型模式·原型原型链
离离茶5 分钟前
【笔记1-11】Qt 关闭QToolbar的拓展菜单
开发语言·笔记·qt
曹牧7 分钟前
C#:窗体构造函数无法引用窗体控件
开发语言·c#
草青工作室9 分钟前
java-FreeMarker3.4自定义异常处理
java·前端·python
xb113210 分钟前
C#使用Cancellation来取消异步任务
开发语言·c#
m0_7482299912 分钟前
C与C#:编程语言的核心差异解析
c语言·开发语言·c#
java1234_小锋19 分钟前
Java中读写锁的应用场景是什么?
java·开发语言