【问题标题】:How to call a Rust function from a Python file using pyo3?如何使用 pyo3 从 Python 文件中调用 Rust 函数?
【发布时间】:2019-06-28 09:02:23
【问题描述】:

我正在开发一个视频游戏,我需要从 Python 文件中设置 Rust 对象(例如,添加一个带有 texture:"", coords:"", text:"", action:"" 的按钮)。

我正在使用 pyo3 crate 来链接 Python 和 Rust。我成功地从我的 Rust 代码调用 Python 脚本,但我找不到如何从 Python 文件调用 Rust 函数。

执行我的 Python 脚本的 Rust 代码:

fn main() -> PyResult<()> {
    let gil = Python::acquire_gil();
    let py = gil.python();
    let script = fs::read_to_string("deep_hello.py")?;

    println!("RUNNING :\n[\n{}]", script);
    py.run(&script, None, None)
}

我想从我的 Python 脚本中调用的 Rust 函数:

/// hello_from_rust(/)
/// --
///
/// This function prints hello because she is very nice.
#[pyfunction]
fn hello_from_rust() {
    println!("Hello from rust from python !");
}

我的 Python 脚本:

hello_from_rust()

我得到这个输出:

RUNNING :
[
hello_from_rust()
]
Error: PyErr { type: Py(0x7f9cdd1e9580, PhantomData) }

【问题讨论】:

    标签: python python-3.x rust pyo3


    【解决方案1】:

    如果我正确理解了您的问题,那么您尝试执行的操作涉及三个步骤:

    1. 创建一个包含函数hello_from_rust()的Python模块
    2. 在 Python 脚本中使用它deep_hello.py
    3. 在 Rust 中运行 deep_hello.py。

    我无法完全重现您的问题,但您的问题的根源似乎在于第一步或第二步。

    使用 PyO3 定义 Python 模块

    从PyO3 documentation 来看,我希望hello_from_rust() 位于定义如下所示Python 模块的Rust 文件中:

    use pyo3::prelude::*;
    use pyo3::wrap_pyfunction;
    
    #[pyfunction]
    fn hello_from_rust() {
        println!("Hello from rust from python !");
    }
    
    #[pymodule]
    fn hello_module(py: Python, m: &PyModule) -> PyResult<()> {
        m.add_wrapped(wrap_pyfunction!(hello_from_rust));
    
        Ok(())
    }
    

    您可以使用 Cargo 将其构建到 Python 模块中(请参阅 here;说明因您的操作系统而略有不同)并将生成的 .so(Linux 或 MacOS)或 .pyd(Windows)文件放在与您的 Python 脚本相同的目录。

    注意

    您必须创建一个类似于hello_module 的函数来初始化您的 Python 模块。如果你不这样做,你的 Rust 库可能仍然可以编译,但你将无法导入 hello_from_rust。

    使用新的 Python 模块

    您的deep_hello.py 脚本应如下所示:

    import hello_module
    hello_module.hello_from_rust()
    

    确保.so 或.pyd 文件可在您的PYTHON_PATH 中访问(例如,将其放在与您的脚本相同的目录中),使用Python >= 3.5 运行deep_hello.py 应该可以工作。 (请注意,您的系统 Python 可能是 Python 2,因此您可能希望使用更新版本的 Python 创建 Anaconda 环境并在其中工作。)

    对我来说,按照这些步骤就可以了。

    (ruspy) ruspy $ python deep_hello.py
    Hello from rust from python !
    

    注意

    确保您记得在 Python 脚本中使用 import hello_module!你的py.run(&amp;script, None, None) 返回的PyErr 让我想知道问题是否真的出在你的 Python 脚本中,事实上我希望没有前面的from deep_hello import * 的hello_from_rust() 会产生一个NameError,即使你把你的deep_hello 模块正确。

    从 Rust 从 Python 调用 Rust

    我不完全确定您为什么要这样做,但您现在应该可以从 Rust 运行 deep_hello.py。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-04
      • 2022-11-09
      • 1970-01-01
      • 2023-03-03
      相关资源
      最近更新 更多