我已经用py03将一些Python重写成了Rust.在我使用的第三方Rust库中的某个地方,我的Rust代码可能会死机.对我来说,最简单的事情就是在Python领域捕捉到这种panic ,并退回到速度较慢(但更有弹性)的Python方法.这种失败是非常罕见的,以至于退回到Python仍然比只使用Python更高效.有没有办法应对铁 rust panic ?根据我所读到的,答案可能是"不",但我希望!

下面是我的意思的简化示例.如有任何帮助,我们不胜感激!

(我知道我可以/可以追查到每一次panic 的具体原因,但我认为这个问题无论如何都有道理.)

lib.rs

use numpy::{IntoPyArray, PyArray1, PyReadonlyArray1};
use pyo3::{pymodule, types::PyModule, PyResult, Python};

#[pymodule]
fn can_panic(_py: Python, m: &PyModule) -> PyResult<()> {
    #[pyfn(m)]
    fn can_panic<'py>(
        py: Python<'py>,
        arr: PyReadonlyArray1<i64>,
    ) -> &'py PyArray1<bool> {
        let my_arr = arr.as_array();
        for v in my_arr {
            if v == &-1 {
                panic!("Hey, you can't do that!");
            }
        }
        vec![true; my_arr.len()].into_pyarray(py)
    }

    Ok(())
}

Cargo.toml

[package]
name = "can_panic"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "can_panic"
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.18.3", features = ["extension-module", "anyhow"] }
numpy = "0.18.0"
nalgebra = "0.32.2"

testing.py

import numpy as np
import can_panic

print("Staring filtering")

print(can_panic.can_panic(np.array([1, 2, 3], dtype="int64")))

print("Done filtering")

print("Staring Filtering")

try:
    print(can_panic.can_panic(np.array([-1, 2, 3], dtype="int64")))
except Exception:
    print("didn't work")
    # call Python equivalent

print("Done filtering")

output

Staring filtering
[ True  True  True]
Done filtering
Staring Filtering
thread '<unnamed>' panicked at 'Hey, you can't do that!', src/lib.rs:16:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Traceback (most recent call last):
  File "(snip...)/can_panic/testing.py", line 13, in <module>
    print(can_panic.can_panic(np.array([-1, 2, 3], dtype="int64")))
pyo3_runtime.PanicException: Hey, you can't do that!

推荐答案

您的except不起作用,因为as pyo3 documents PanicException派生自BaseException(如SystemExitKeyboardError),因为它不一定是安全的(给定不是所有的 rust 代码都是panic 安全的,pyo3并不假设 rust 级panic 是无害的).

那么,你的 Select 将是,按合意的降序排列(就我而言):

  • 改进第三方库或您对它的调用,这样它就不会panic
  • 在铁 rust 一侧使用catch_unwind,并将panic 转换为更典型的错误
  • 具体地捕捉PanicException,这并不是很好(可能也不容易),因为您可能不想捕捉BaseException

Rust相关问答推荐

关联类型(类型参数)命名约定

为什么实例方法可以像Rust中的静态方法一样被调用?

为什么这是&q;,而让&q;循环是无限循环?

在Rust中是否可以使用Rc自动化约束传播

创建Rust中元对象协议的动态对象 Select /重新分配机制

避免在Collect()上进行涡鱼类型的涂抹,以产生<;Vec<;_>;,_>;

在macro_rule中拆分模块和函数名

不同类型泛型的映射

考虑到Rust不允许多个可变引用,类似PyTorch的自动区分如何在Rust中工作?

为什么我需要 to_string 函数的参考?

为什么实现特征的对象期望比具体对象有更长的生命周期?

try 实现线程安全的缓存

具有多个键的 HashMap

Rust: 目标成员属于哪个"目标家族"的列表是否存在?

如何在 Rust 中按 char 对字符串向量进行排序?

在构建器模式中捕获 &str 时如何使用生命周期?

在单独的线程上运行 actix web 服务器

需要括号的宏调用中的不必要的括号警告 - 这是编写宏的糟糕方法吗?

传递 Option<&mut T> 时何时需要 mut

list 中没有指定目标 - 必须存在 src/lib.rs、src/main.rs、[lib] 部分或 [[bin]] 部分