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

执行结果

相关推荐
Csvn16 小时前
🌟 LangChain 30 天保姆级教程 · Day 13|OutputParser 进阶!让 AI 输出自动转为结构化对象,并支持自动重试!
python·langchain
Wenweno0o16 小时前
0基础Go语言Eino框架智能体实战-chatModel
开发语言·后端·golang
chenjingming66617 小时前
jmeter线程组设置以及串行和并行设置
java·开发语言·jmeter
cch891817 小时前
Python主流框架全解析
开发语言·python
不爱吃炸鸡柳17 小时前
C++ STL list 超详细解析:从接口使用到模拟实现
开发语言·c++·list
十五年专注C++开发17 小时前
RTTR: 一款MIT 协议开源的 C++ 运行时反射库
开发语言·c++·反射
Momentary_SixthSense17 小时前
设计模式之工厂模式
java·开发语言·设计模式
sg_knight17 小时前
设计模式实战:状态模式(State)
python·ui·设计模式·状态模式·state
Tomhex17 小时前
Rust数组与Vec的核心差异解析
rust
好运的阿财17 小时前
process 工具与子agent管理机制详解
网络·人工智能·python·程序人生·ai编程