我写了Rust代码:
myapp/src/main.rs
extern crate cpython;
use cpython::Python;
fn main() {
let gil = Python::acquire_gil();
println!("Hello from Rust!");
let py = gil.python();
let module = cpython::PyModule::import(py, "fibo").unwrap();
module.call(py, "fib", (1,), None).unwrap();
}
并将Python模块保存为myapp/pyth/fibo.py
但是我得到了错误:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: PyErr { ptype: <class 'ModuleNotFoundError'>, pvalue: Some(ModuleNotFoundError("No module named 'fibo'",)), ptraceback: None }', libcore/result.rs:945:5
我希望了解有关目录pyth
的部分代码是:let module = cpython::PyModule::import(py, "fibo").unwrap();
答案 0 :(得分:1)
如果您想将fibo.py
与可执行文件分开保存,则有两种解决方案:
pyth
文件夹添加到Python路径:let sys = py.import("sys")?;
PyList::downcast_from(py, sys.get("path")?)?.insert_item(py, 0, "pyth");
let module = py.import("fibo")?;
这假定Rust可执行文件是从父文件夹或项目运行的,这意味着pyth
是当前路径的子文件夹。
pyth.fibo
,就像在Python中那样:let module = py.import("pyth.fibo")?;
这假定pyth
在Python路径中(如果需要将父文件夹添加到路径中,请参阅第一个解决方案)。
答案 1 :(得分:0)
我找到了解决方法。
main.rs
extern crate cpython;
use cpython::{PyModule, PyResult, Python};
const FIBO_PY: &'static str = include_str!("../pyth/fibo.py");
fn main() {
let gil = Python::acquire_gil();
let py = gil.python();
example(py).unwrap();
}
fn example(py: Python<'_>) -> PyResult<()> {
let m = module_from_str(py, "fibo", FIBO_PY)?;
let out: Vec<i32> = m.call(py, "fib", (2,), None)?.extract(py)?;
println!(
"successfully found fibo.py at compiletime. Output: {:?}",
out
);
Ok(())
}
/// Import a module from the given file contents.
///
/// This is a wrapper around `PyModule::new` and `Python::run` which simulates
/// the behavior of the builtin function `exec`. `name` will be used as the
/// module's `__name__`, but is not otherwise important (it does not need
/// to match the file's name).
fn module_from_str(py: Python<'_>, name: &str, source: &str) -> PyResult<PyModule> {
let m = PyModule::new(py, name)?;
let builtins = cpython::PyModule::import(py, "builtins").unwrap();
m.dict(py).set_item(py, "__builtins__", &builtins).unwrap();
// OR
m.add(py, "__builtins__", py.import("builtins")?)?;
let m_locals = m.get(py, "__dict__")?.extract(py)?;
// To avoid multiple import, and to add entry to the cache in `sys.modules`.
let sys = cpython::PyModule::import(py, "sys").unwrap();
sys.get(py, "modules").unwrap().set_item(py, name, &m).unwrap();
// Finally, run the moduke
py.run(source, Some(&m_locals), None)?;
Ok(m)
}
fibo.py
def fib(n): # return Fibonacci series up to n
print('Hello from python!')
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result