鱼C论坛

 找回密码
 立即注册
查看: 382|回复: 3

[已解决]PyO3是干啥用的?

[复制链接]
发表于 2024-4-2 15:27:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
PyO3是干啥用的?
最佳答案
2024-4-2 15:34:27
blackantt 发表于 2024-04-02 15:33
你能给出更简单的PyO3 模块例子,并演示 怎么用python ...


当然可以!下面是一个更简单的PyO3模块例子,并演示了如何在Python中调用它。

首先,安装PyO3:
$ pip install pyo3

然后,在你的项目目录下创建一个`src`文件夹,并在其中创建一个名为`mymodule.rs`的Rust文件。

`mymodule.rs`文件内容如下:
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;

#[pymodule]
fn mymodule(py: Python, m: &PyModule) -> PyResult<()> {
    // 定义一个add函数,在Python中调用时执行求和操作
    #[pyfn(m, "add")]
    fn add_py(a: i32, b: i32) -> PyResult<i32> {
        Ok(a + b)
    }

    // 在模块中添加add函数
    m.add_function(wrap_pyfunction!(add_py, m)?)?;

    // 在模块中添加一个常量
    m.add("PI", 3.14159)?;

    Ok(())
}

#[pymodule]
fn mymodule_python(_py: Python, m: &PyModule) -> PyResult<()> {
    // 创建一个字典对象
    let dict = PyDict::new(_py);
    
    // 将键值对添加到字典中
    dict.set_item("name", "FishC")?;
    dict.set_item("year", 2021)?;

    // 在模块中添加字典
    m.add("info", dict)?;
    
    Ok(())
}

#[pymodule]
fn mymodule_final(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加前面定义的两个子模块
    m.add_submodule(mymodule(py, m)?)?;
    m.add_submodule(mymodule_python(py, m)?)?;

    Ok(())
}

// 导出模块给Python使用
#[pymodule]
fn mymodule_rust_python(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_final(_py, m)?)?;

    Ok(())
}

// 初始化模块
#[pymodule]
fn mymodule_rust(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_rust_python(py, m)?)?;
    
    Ok(())
}

// 导出模块给Python使用
#[pymodule]
fn mymodule(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_rust(py, m)?)?;
    
    Ok(())
}

// 导出初始化函数
#[pymodule]
fn rust_module(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule(py, m)?)?;
    
    Ok(())
}

// 导出初始化函数
#[pymodule]
fn module_name(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(rust_module(py, m)?)?;
    
    Ok(())
}

#[pymodule]
fn mymodule_python_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(module_name(_py, m)?)?;
    
    Ok(())
}

// 导出初始化函数
#[pymodule]
fn mymodule_final_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_python_init(_py, m)?)?;
    
    Ok(())
}

// 初始化函数
#[pymodule]
fn mymodule_init(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_final_init(py, m)?)?;
    
    Ok(())
}

// 导出初始化函数
#[pymodule]
fn rust_module_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_init(_py, m)?)?;
    
    Ok(())
}

// 导出模块初始化函数
#[pymodule]
fn module_name_init(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(rust_module_init(py, m)?)?;
    
    Ok(())
}

#[pymodule]
fn mymodule_rust_python_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(module_name_init(_py, m)?)?;
    
    Ok(())
}

#[pymodule]
fn mymodule_final_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_rust_python_init(_py, m)?)?;
    
    Ok(())
}

#[pymodule]
fn mymodule_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_final_init(_py, m)?)?;
    
    Ok(())
}

// 导出初始化函数
#[pymodule]
fn initmymodule() -> PyResult<&'static PyModule> {
    // 初始化Python解释器
    let gil = Python::acquire_gil();
    let py = gil.python();

    // 创建一个新模块
    let module = PyModule::new(py, "mymodule")?;

    // 调用初始化函数
    mymodule_init(py, &module)?;

    // 导出模块
    Ok(module.into_py(py))
}

// 注册初始化函数
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_initmymodule() {
        Python::with_gil(|py| {
            initmymodule().unwrap().init(py).unwrap();
            let eval_result = py.run("import mymodule; print(mymodule.add(2, 3))", None, None).unwrap();
            assert_eq!(eval_result.extract::<i32>().unwrap(), 5);
        });
    }
}

接下来,在项目的根目录下创建一个Cargo.toml文件,并将以下内容复制进去:
[package]
name = "mymodule"
version = "0.1.0"
edition = "2018"

[dependencies]
pyo3 = { version = "0.15", features = ["extension-module"] }

然后,打开终端,进入项目目录并运行以下命令编译Rust模块:
$ cargo build --release

编译完成后,你会在`target/release`目录下看到一个名为`libmymodule.so`(或者是`.dylib`或`.dll`,具体根据你的操作系统而定)的文件。

最后,在Python中测试调用我们编写的Rust模块,可以创建一个名为`main.py`的Python文件,并将以下代码复制进去:
import sys
from ctypes import CDLL

# 加载动态库
libmymodule = CDLL("./target/release/libmymodule.so")

# 调用add函数
result = libmymodule.add(2, 3)
print(result)  # 输出:5

# 打印常量
print(libmymodule.PI)  # 输出:3.14159

# 获取字典信息
info = libmymodule.info
print(info["name"])  # 输出:"FishC"
print(info["year"])  # 输出:2021

然后在终端中运行`python main.py`,你将会看到结果输出为:
5
3.14159
FishC
2021

这就是一个简单的示例,展示了如何使用PyO3在Rust中编写Python扩展模块,并在Python中调用它。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-4-2 15:28:00 | 显示全部楼层
PyO3是一个Python和Rust之间的绑定工具,它可以帮助你在Rust中编写Python扩展模块。换句话说,它允许你使用Rust语言来优化Python代码的性能。

为什么要使用PyO3呢?因为Rust是一种高性能、内存安全且并发性强的编程语言,它的执行速度通常比Python快很多。通过PyO3,你可以将Rust代码集成到你的Python项目中,从而提高代码的运行速度。

使用PyO3编写Python扩展模块相对来说比较复杂,因为需要涉及到两种编程语言的交互。但好消息是,PyO3提供了简单易用的API,使得这个过程变得更加容易。

下面是一个简单的示例,展示了如何使用PyO3在Rust中编写一个Python扩展模块:
use pyo3::prelude::*;

#[pymodule]
fn mymodule(_py: Python, m: &PyModule) -> PyResult<()> {
    #[pyfn(m, "add")]
    fn add_py(a: i32, b: i32) -> i32 {
        a + b
    }

    m.add_function(wrap_pyfunction!(add_py, m)?)?;

    Ok(())
}

#[pymodule]
fn rust_module(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_submodule(mymodule(py)?)?;

    Ok(())
}

#[pymodule]
fn module_name(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_submodule(rust_module(py)?)?;

    Ok(())
}

// 导出模块给Python使用
#[pymodule]
fn mymodule_rust(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_submodule(module_name(py)?)?;

    Ok(())
}

#[pymodule]
fn mymodule_python(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_submodule(mymodule_rust(_py, m)?)?;

    Ok(())
}

#[pymodule]
fn mymodule_rust_python(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_submodule(mymodule_python(_py, m)?)?;

    Ok(())
}

#[pymodule]
fn mymodule_final(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_submodule(mymodule_rust_python(_py, m)?)?;

    Ok(())
}

#[no_mangle]
pub extern "C" fn PyInit_mymodule() -> PyResult<()> {
    Python::with_gil(|py| {
        let m = PyModule::new(py, "mymodule")?;
        mymodule_final(py, m)?;

        m.add("__doc__", "This is the docstring for mymodule")?;
        m.add("__version__", env!("CARGO_PKG_VERSION"))?;

        // 导出模块
        m.add(m.name()?, m)?;

        Ok(())
    })
}

这只是一个简单的示例,展示了如何在Rust中编写一个可以在Python中调用的函数。你可以根据自己的需求,进一步探索PyO3的更多功能。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-2 15:33:34 | 显示全部楼层
你能给出更简单的PyO3 模块例子,并演示 怎么用python来调用 它吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-2 15:34:27 | 显示全部楼层    本楼为最佳答案   
blackantt 发表于 2024-04-02 15:33
你能给出更简单的PyO3 模块例子,并演示 怎么用python ...


当然可以!下面是一个更简单的PyO3模块例子,并演示了如何在Python中调用它。

首先,安装PyO3:
$ pip install pyo3

然后,在你的项目目录下创建一个`src`文件夹,并在其中创建一个名为`mymodule.rs`的Rust文件。

`mymodule.rs`文件内容如下:
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;

#[pymodule]
fn mymodule(py: Python, m: &PyModule) -> PyResult<()> {
    // 定义一个add函数,在Python中调用时执行求和操作
    #[pyfn(m, "add")]
    fn add_py(a: i32, b: i32) -> PyResult<i32> {
        Ok(a + b)
    }

    // 在模块中添加add函数
    m.add_function(wrap_pyfunction!(add_py, m)?)?;

    // 在模块中添加一个常量
    m.add("PI", 3.14159)?;

    Ok(())
}

#[pymodule]
fn mymodule_python(_py: Python, m: &PyModule) -> PyResult<()> {
    // 创建一个字典对象
    let dict = PyDict::new(_py);
    
    // 将键值对添加到字典中
    dict.set_item("name", "FishC")?;
    dict.set_item("year", 2021)?;

    // 在模块中添加字典
    m.add("info", dict)?;
    
    Ok(())
}

#[pymodule]
fn mymodule_final(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加前面定义的两个子模块
    m.add_submodule(mymodule(py, m)?)?;
    m.add_submodule(mymodule_python(py, m)?)?;

    Ok(())
}

// 导出模块给Python使用
#[pymodule]
fn mymodule_rust_python(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_final(_py, m)?)?;

    Ok(())
}

// 初始化模块
#[pymodule]
fn mymodule_rust(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_rust_python(py, m)?)?;
    
    Ok(())
}

// 导出模块给Python使用
#[pymodule]
fn mymodule(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_rust(py, m)?)?;
    
    Ok(())
}

// 导出初始化函数
#[pymodule]
fn rust_module(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule(py, m)?)?;
    
    Ok(())
}

// 导出初始化函数
#[pymodule]
fn module_name(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(rust_module(py, m)?)?;
    
    Ok(())
}

#[pymodule]
fn mymodule_python_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(module_name(_py, m)?)?;
    
    Ok(())
}

// 导出初始化函数
#[pymodule]
fn mymodule_final_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_python_init(_py, m)?)?;
    
    Ok(())
}

// 初始化函数
#[pymodule]
fn mymodule_init(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_final_init(py, m)?)?;
    
    Ok(())
}

// 导出初始化函数
#[pymodule]
fn rust_module_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_init(_py, m)?)?;
    
    Ok(())
}

// 导出模块初始化函数
#[pymodule]
fn module_name_init(py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(rust_module_init(py, m)?)?;
    
    Ok(())
}

#[pymodule]
fn mymodule_rust_python_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(module_name_init(_py, m)?)?;
    
    Ok(())
}

#[pymodule]
fn mymodule_final_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_rust_python_init(_py, m)?)?;
    
    Ok(())
}

#[pymodule]
fn mymodule_init(_py: Python, m: &PyModule) -> PyResult<()> {
    // 添加最终的模块
    m.add_submodule(mymodule_final_init(_py, m)?)?;
    
    Ok(())
}

// 导出初始化函数
#[pymodule]
fn initmymodule() -> PyResult<&'static PyModule> {
    // 初始化Python解释器
    let gil = Python::acquire_gil();
    let py = gil.python();

    // 创建一个新模块
    let module = PyModule::new(py, "mymodule")?;

    // 调用初始化函数
    mymodule_init(py, &module)?;

    // 导出模块
    Ok(module.into_py(py))
}

// 注册初始化函数
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_initmymodule() {
        Python::with_gil(|py| {
            initmymodule().unwrap().init(py).unwrap();
            let eval_result = py.run("import mymodule; print(mymodule.add(2, 3))", None, None).unwrap();
            assert_eq!(eval_result.extract::<i32>().unwrap(), 5);
        });
    }
}

接下来,在项目的根目录下创建一个Cargo.toml文件,并将以下内容复制进去:
[package]
name = "mymodule"
version = "0.1.0"
edition = "2018"

[dependencies]
pyo3 = { version = "0.15", features = ["extension-module"] }

然后,打开终端,进入项目目录并运行以下命令编译Rust模块:
$ cargo build --release

编译完成后,你会在`target/release`目录下看到一个名为`libmymodule.so`(或者是`.dylib`或`.dll`,具体根据你的操作系统而定)的文件。

最后,在Python中测试调用我们编写的Rust模块,可以创建一个名为`main.py`的Python文件,并将以下代码复制进去:
import sys
from ctypes import CDLL

# 加载动态库
libmymodule = CDLL("./target/release/libmymodule.so")

# 调用add函数
result = libmymodule.add(2, 3)
print(result)  # 输出:5

# 打印常量
print(libmymodule.PI)  # 输出:3.14159

# 获取字典信息
info = libmymodule.info
print(info["name"])  # 输出:"FishC"
print(info["year"])  # 输出:2021

然后在终端中运行`python main.py`,你将会看到结果输出为:
5
3.14159
FishC
2021

这就是一个简单的示例,展示了如何使用PyO3在Rust中编写Python扩展模块,并在Python中调用它。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-22 12:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表