14

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

我正在使用 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) }
4

1 回答 1

5

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

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

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

使用 PyO3 定义 Python 模块

PyO3 文档中,我希望hello_from_rust()在一个 Rust 文件中定义一个看起来像这样的 Python 模块:

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 模块中(参见此处;说明因您的操作系统而略有不同),并将生成的.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()

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

对我来说,遵循这些步骤就可以了。

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

笔记

确保你记得import hello_module在你的 Python 脚本中!PyErr你返回的结果py.run(&script, None, None)让我想知道问题是否真的出在你的 Python 脚本中,而且我确实希望hello_from_rust()没有前面的内容from deep_hello import *会产生 a NameError,即使你deep_hello正确地组合了你的模块。

从 Rust 从 Python 调用 Rust

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

于 2020-05-24T16:24:36.863 回答