这可能记录在 PyO3 文档中的某处,但我找不到它。
我用Python创建了一个这样的类:
class ProgressData():
def __init__(self):
self.start_time_ms = 0
self.last_progress_percent = 0.0
...我实例化它并将其传递给具有以下签名的 Rust 模块:
#[pyfunction]
fn index_documents(py: Python, progress_data: ProgressData) -> PyResult<()> {
...
我在 Rust 模块中定义了一个“等效”
struct
:
#[derive(Clone)]
#[pyclass]
pub struct ProgressData {
start_time_ms: usize,
last_progress_percent: f64,
}
我已将其添加为可导出类之一:
#[pymodule]
#[pyo3(name = "populate_index")]
fn my_extension(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(index_documents, m)?)?;
m.add_class::<HandlingFramework>()?;
m.add_class::<TextDocument>()?;
m.add_class::<ProgressData>()?;
Ok(())
}
...但它不起作用:我明白了
参数“progress_data”:“ProgressData”对象无法转换为“ProgressData”
无需进一步解释。
上面的类“HandlingFramework”和“TextDocument”是用 Rust 创建的,并导出到 Python,可以使用它们的属性和方法。有没有办法反过来做(用Python制作,用Rust使用)?或者也许唯一的方法是在 Rust 模块中创建一个工厂函数,将一个
ProgressData
对象传递给 Python,将数据放入其中,然后将其重新导出到 Rust 模块中的另一个函数?
我还想为
ProgressData
定义几个方法:同样,有任何方法可以在 Python 中定义它,但 Rust 是否接受它作为等效 Rust struct
+ impl
的鞋履?
Masklinn 给我指出了手册的右侧部分。
但事实上,我发现在这种情况下实现工厂方法解决方案对我来说可能是最简单的解决方案:不需要乱搞
py
对象。
#[derive(Clone)]
#[pyclass]
pub struct ProgressData {
#[pyo3(get, set)]
start_time_ms: usize,
#[pyo3(get, set)]
last_progress_percent: f64,
}
#[pyfunction]
fn new_progress_data(py: Python) -> ProgressData {
ProgressData {
start_time_ms: 0,
last_progress_percent: 0.0,
}
}
...我可以快速在 Python 代码中创建一个实例,并处理数据后将其重新导出到 Rust
index_documents
函数...并且 ProgressData
参数毫无杂音地被接受。显然Python类定义已经被删除了。