当然可以!下面是一个更简单的PyO3模块例子,并演示了如何在Python中调用它。
首先,安装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模块:
编译完成后,你会在`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`,你将会看到结果输出为:
这就是一个简单的示例,展示了如何使用PyO3在Rust中编写Python扩展模块,并在Python中调用它。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |