1. 当前位置:网站首页 > Python

pyo3(rust包的)测试


实际使用时,pyo3可以直接打包成pip里的包使用

性能上还是cython出色一点,不过也有可能是数据类型转换导致的性能差异

步骤:

  • 安装rust 下载rustup-init.exe 执行后cmd窗口选择1即可,安装完后使用 https://www.rust-lang.org/tools/install

    执行 有版本出现代表成功C:\Users\liuyang>rustc --version
    rustc 1.73.0 (cc66ad468 2023-10-03)

  • 移除多环境,因为我同时有虚拟环境和anconda的环境,无法编译

    Caused by: Both VIRTUAL_ENV and CONDA_PREFIX are set. Please unset one of them
    执行即可 set CONDA_PREFIX=

  • 安装python包

    pip install maturin
    新建目录,这个目录将默认作为包的名字 mkdir rust_deal
    cd rust_deal
    maturin init

  • 会创建pyproject.toml 文件 Cargo.toml文件和scr目录,目录中有lib.rs

    主要就是修改lib.rs文件
    修改对应的rs函数,执行编译指令
    maturin develop # 这里用梯子下载对应的包还是慢的,偶尔会报timeout,建议用香港节点还挺快的,只用下载一次

  • 编译成功就会把当前包安装到对应的python环境内,使用pip list上可以看到对应的包名

    临时调试,这里是用生成的默认代码进行的论证

    $ python
    >> import rust_deal               
    >> rust_deal.sum_as_string(5, 20) 
    '25'

一个项目上的代码(实测还是cython的效率高一点,不过也有可能是因为数据类型转换的原因导致的处理时间变长)

use pyo3::prelude::*;
use pyo3::types::PyList;
use pyo3::types::PyDict;

/// 定义与自定义 Python 对象 `TargetStructReturn` 对应的 Rust 结构体
#[pyclass]
struct TargetStructReturn {
    fAmp: f64,
    SNR: f64,
    azimuth: f64,
    AnglePitch: f64,
    radial_velocity: f64,
    range: f64,
    RCS: f64,
    range_var: f64,
    AnglePitch_var: f64,
    azimuth_var: f64,
    RCS_var: f64,
    target_confidence: i32,
    azimuth_confidence: i32,
    velocity_confidence: i32,
    multipath_probability: f64,
    predict_range: f64,
    false_target_probability: f64,
    x: f64,
    y: f64,
    z: f64,
    AngularResolutionFlag: bool,
    PeakFlag: i32,
}

// 实现 FromPyObject<'a> trait,将 Python 对象转换为 Rust 结构体
impl FromPyObject<'_> for TargetStructReturn {
    fn extract(obj: &PyAny) -> PyResult<Self> {
        // 从 Python 对象中提取并初始化结构体字段
        let fAmp = obj.getattr("fAmp")?.extract()?;
        let SNR = obj.getattr("SNR")?.extract()?;
        let azimuth = obj.getattr("azimuth")?.extract()?;
        let AnglePitch = obj.getattr("AnglePitch")?.extract()?;
        let radial_velocity = obj.getattr("radial_velocity")?.extract()?;
        let range = obj.getattr("range")?.extract()?;
        let RCS = obj.getattr("RCS")?.extract()?;
        let range_var = obj.getattr("range_var")?.extract()?;
        let AnglePitch_var = obj.getattr("AnglePitch_var")?.extract()?;
        let azimuth_var = obj.getattr("azimuth_var")?.extract()?;
        let RCS_var = obj.getattr("RCS_var")?.extract()?;
        let target_confidence = obj.getattr("target_confidence")?.extract()?;
        let azimuth_confidence = obj.getattr("azimuth_confidence")?.extract()?;
        let velocity_confidence = obj.getattr("velocity_confidence")?.extract()?;
        let multipath_probability = obj.getattr("multipath_probability")?.extract()?;
        let predict_range = obj.getattr("predict_range")?.extract()?;
        let false_target_probability = obj.getattr("false_target_probability")?.extract()?;
        let x = obj.getattr("x")?.extract()?;
        let y = obj.getattr("y")?.extract()?;
        let z = obj.getattr("z")?.extract()?;
        let AngularResolutionFlag = obj.getattr("AngularResolutionFlag")?.extract()?;
        let PeakFlag = obj.getattr("PeakFlag")?.extract()?;

        // 构建结构体
        Ok(TargetStructReturn {
            fAmp,
            SNR,
            azimuth,
            AnglePitch,
            radial_velocity,
            range,
            RCS,
            range_var,
            AnglePitch_var,
            azimuth_var,
            RCS_var,
            target_confidence,
            azimuth_confidence,
            velocity_confidence,
            multipath_probability,
            predict_range,
            false_target_probability,
            x,
            y,
            z,
            AngularResolutionFlag,
            PeakFlag,
        })
    }
}

// 实现 IntoPy<PyObject> trait,将 Rust 结构体转换为 Python 对象
impl IntoPy<PyObject> for &TargetStructReturn {
    fn into_py(self, py: Python) -> Py<PyAny> {
        // 创建一个 Python 字典对象,并为其设置字段
        let obj = PyDict::new(py);
        obj.set_item("fAmp", self.fAmp).unwrap();
        obj.set_item("SNR", self.SNR).unwrap();
        obj.set_item("azimuth", self.azimuth).unwrap();
        obj.set_item("AnglePitch", self.AnglePitch).unwrap();
        obj.set_item("radial_velocity", self.radial_velocity).unwrap();
        obj.set_item("range", self.range).unwrap();
        obj.set_item("RCS", self.RCS).unwrap();
        obj.set_item("range_var", self.range_var).unwrap();
        obj.set_item("AnglePitch_var", self.AnglePitch_var).unwrap();
        obj.set_item("azimuth_var", self.azimuth_var).unwrap();
        obj.set_item("RCS_var", self.RCS_var).unwrap();
        obj.set_item("target_confidence", self.target_confidence).unwrap();
        obj.set_item("azimuth_confidence", self.azimuth_confidence).unwrap();
        obj.set_item("velocity_confidence", self.velocity_confidence).unwrap();
        obj.set_item("multipath_probability", self.multipath_probability).unwrap();
        obj.set_item("predict_range", self.predict_range).unwrap();
        obj.set_item("false_target_probability", self.false_target_probability).unwrap();
        obj.set_item("x", self.x).unwrap();
        obj.set_item("y", self.y).unwrap();
        obj.set_item("z", self.z).unwrap();
        obj.set_item("AngularResolutionFlag", self.AngularResolutionFlag).unwrap();
        obj.set_item("PeakFlag", self.PeakFlag).unwrap();
        obj.into()
    }
}

/// A struct representing target information.
#[pyclass]
struct TargetInfo {
    custom_data: TargetStructReturn,
    // 继续添加与目标信息相关的字段
    // 例如:distance_rms: f64, velocity_rms: f64, ...
}

#[pymodule]
fn rust_deal(_py: Python, m: &PyModule) -> PyResult<()> {
    // 注册 TargetStructReturn 和 TargetInfo 结构体作为 Python 类
    m.add_class::<TargetStructReturn>()?;
    m.add_class::<TargetInfo>()?;

    // 注册 `deal` 函数
    m.add_function(wrap_pyfunction!(deal, m)?)?;

    Ok(())
}

/// 从 Python 列表中处理目标信息
#[pyfunction]
fn deal(_py: Python, target_array: &PyList) -> PyResult<Vec<Py<PyDict>>> {
    let mut target_info_list = Vec::new();
//     let mut sp_target = Vec::new();
//     let mut height = PyDict::new(_py);
    for (index, item) in target_array.iter().enumerate() {
        // 提取和处理自定义 Python 对象
        let custom_data = item.extract::<TargetStructReturn>()?;

        // 创建一个 Python 字典对象,设置字段值
        let mut dict = PyDict::new(_py);
        dict.set_item("VelocityUnit", 0)?;
        dict.set_item("DistanceUnit", 0)?;
        dict.set_item("AzimuthUnit", 0)?;
        dict.set_item("ElevationUnit", 0)?;

        dict.set_item("Amplitude", custom_data.fAmp)?;
        dict.set_item("SNR", custom_data.SNR)?;
        dict.set_item("Azimuth", custom_data.azimuth)?;
        dict.set_item("Elevation", custom_data.AnglePitch)?;
        dict.set_item("RadialVelocity", custom_data.radial_velocity)?;

        dict.set_item("Range", custom_data.range)?;
        dict.set_item("RCS", custom_data.RCS)?;

        dict.set_item("Distance_rms", custom_data.range_var)?;
        dict.set_item("Velocity_rms", custom_data.AnglePitch_var)?;
        dict.set_item("Azimuth_rms", custom_data.azimuth_var)?;
        dict.set_item("Elevation_rms", custom_data.AnglePitch_var)?;
        dict.set_item("RCS_rms", custom_data.RCS_var)?;

        dict.set_item("target_iD", index)?;
        dict.set_item("AngleResolutionFlag", custom_data.AngularResolutionFlag)?;
        dict.set_item("PeakFlag", custom_data.PeakFlag)?;
        dict.set_item("VelocityAmbiguousState", custom_data.velocity_confidence)?;
        dict.set_item("TargetConfidence", custom_data.target_confidence)?;
        dict.set_item("AngleConfidence", custom_data.azimuth_confidence)?;
        dict.set_item("MultipathProbability", custom_data.multipath_probability)?;
        dict.set_item("PredictedRadialDistance", custom_data.predict_range)?;
        dict.set_item("GhostTargetProbability", custom_data.false_target_probability)?;
        let xyz_array = vec![custom_data.y, custom_data.x, custom_data.z];
        dict.set_item("xyz", xyz_array)?;

        target_info_list.push(dict.into());
    }

    Ok(target_info_list)
}

本文最后更新于2023-10-16,已超过 3个月没有更新,如果文章内容或图片资源失效,请留言反馈,我们会及时处理,谢谢!
版权说明

本文地址:http://www.liuyangdeboke.cn/?post=57
未标注转载均为本站远程,转载请注明文章出处:

发表评论

联系我们

在线咨询:点击这里给我发消息

微信号:17721538135

工作日:9:00-23:00,节假日休息

扫码关注