Как вызвать функцию ржавчины из файла 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 ответов
Если я правильно понял вашу проблему, то, что вы пытаетесь сделать, состоит из трех шагов:
- Создайте модуль Python, содержащий функцию
hello_from_rust()
- Используйте его в скрипте Python
deep_hello.py
- Бегать
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
из ржавчины.