Как вызвать функцию ржавчины из файла Python, используя pyo3?

Я работаю над видео-игрой, в которой мне нужно установить объекты ржавчины (например, добавить кнопку с текстурой: "" координирование: "" текст: "" действие:"") из файлов Python.

Я использую ящик pyo3, чтобы связать Python и ржавчину.

Мне удалось вызвать скрипты Python из моего кода ржавчины.

Но я не могу найти, как вызвать функцию ржавчины из файла Python.

Rust Code, который выполняет мой скрипт на python:

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)
}

Функция Rust, которую я хотел бы вызвать из моего скрипта Python:

/// 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) }

0 ответов

Если я правильно понял вашу проблему, то, что вы пытаетесь сделать, состоит из трех шагов:

  1. Создайте модуль Python, содержащий функцию hello_from_rust()
  2. Используйте его в скрипте Python deep_hello.py
  3. Бегать deep_hello.py изнутри Rust.

Мне не удалось полностью воспроизвести вашу проблему, но похоже, что корень вашей проблемы может быть на первом или втором шаге.

Определение модуля Python с использованием PyO3

Из документации 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(())
}

Вы можете встроить это в модуль Python с помощью Cargo (см. Здесь; инструкции немного отличаются в зависимости от вашей ОС) и поместить полученный.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 (например, поместив его в тот же каталог, что и ваш скрипт), запустив deep_hello.pyс Python >= 3.5 должно работать. (Обратите внимание, что ваша система Python, вероятно, Python 2, поэтому вы можете создать среду Anaconda с более новой версией Python и работать оттуда.)

Для меня выполнение этих шагов помогло.

(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 * произвести NameError, даже если вы соберете deep_hello модуль правильно.

Вызов Rust из Python из Rust

Я не совсем уверен, почему вы хотите это сделать, но теперь вы можете запустить deep_hello.py из ржавчины.

Другие вопросы по тегам