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

执行结果

相关推荐
你怎么知道我是队长12 小时前
C语言---枚举变量
c语言·开发语言
李慕婉学姐12 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
吃茄子的猫12 小时前
quecpython中&的具体含义和使用场景
开发语言·python
じ☆冷颜〃12 小时前
黎曼几何驱动的算法与系统设计:理论、实践与跨领域应用
笔记·python·深度学习·网络协议·算法·机器学习
云栖梦泽12 小时前
易语言中小微企业Windows桌面端IoT监控与控制
开发语言
数据大魔方12 小时前
【期货量化实战】日内动量策略:顺势而为的短线交易法(Python源码)
开发语言·数据库·python·mysql·算法·github·程序员创富
APIshop13 小时前
Python 爬虫获取 item_get_web —— 淘宝商品 SKU、详情图、券后价全流程解析
前端·爬虫·python
风送雨13 小时前
FastMCP 2.0 服务端开发教学文档(下)
服务器·前端·网络·人工智能·python·ai
效率客栈老秦13 小时前
Python Trae提示词开发实战(8):数据采集与清洗一体化方案让效率提升10倍
人工智能·python·ai·提示词·trae
哈里谢顿13 小时前
一条 Python 语句在 C 扩展里到底怎么跑
python