[英]Generic function argument that accepts functions that implement a macro
I'm using pyo3 to add some rust to my python project (for performance), and wanted to create a function to make adding submodules easier.我正在使用 pyo3 将一些 rust 添加到我的 python 项目中(出于性能考虑),并希望创建一个 function 以更轻松地添加子模块。 My current code:
我当前的代码:
fn register_submodule(name: &str, python: Python, parent: &PyModule, funcs: Vec<?>) -> PyResult<()> {
let name = &(parent.name()?.to_owned() + name);
let child = PyModule::new(python, name)?;
for func in &funcs {
child.add_function(wrap_pyfunction!(func, child)?)?;
}
py_run!(python, child, format!("import sys; sys.modules[{}] = child_module", name).as_str());
parent.add_submodule(child)?;
Ok(())
}
I want this function to be able to take an array or vector (or whatever) containing functions that implement the #[PyFunction]
macro, take any arguments of any type and return a PyResult containing any type, so I can register these to the new module.我希望这个 function 能够采用包含实现
#[PyFunction]
宏的函数的数组或向量(或其他),采用任何类型的 arguments 并返回包含任何类型的 PyResult,所以我可以将这些注册到新的模块。 Is this possible?这可能吗? How would I go about doing it, or achieving a similar result?
我将如何 go 做到这一点,或取得类似的结果? Any help would be much appreciated!
任何帮助将非常感激!
There is no way to do it, either no way to pass vector with different functions.没有办法做到这一点,也没有办法传递具有不同功能的向量。 Because functions in
Vector
may be very different, may accept different type/count of arguments (how rust will know how to call/use that functions).因为
Vector
中的函数可能非常不同,可能会接受不同类型/计数的 arguments(rust 将如何知道如何调用/使用该函数)。
The only way to achieve this is with Enums
.实现这一点的唯一方法是使用
Enums
。
Create Enum
with variants of all Python functions eg.使用所有 Python 函数的变体创建
Enum
,例如。
enum PyFunctionVariant {
F1(fn(param1: i32, param2: i32) -> PyResult),
F2(fn(param1: &str, param2: &str) -> PyResult),
// all your function definitions
}
Change register_submodule
declaration to accept Vec
of PyFunctionVariant
.更改
register_submodule
声明以接受PyFunctionVariant
的Vec
。
fn register_submodule(name: &str, python: Python, parent: &PyModule, funcs: Vec<PyFunctionVariant>) -> PyResult<()> {
...
}
You may also need to change this part with match
, because now func
is Enum
not PyFunction.您可能还需要使用
match
更改此部分,因为现在func
是Enum
而不是 PyFunction。
for func in &funcs {
child.add_function(wrap_pyfunction!(func, child)?)?; // Change Here
}
and use this way并使用这种方式
let functions = vec![
PyFunctionVariant::F1(add_int),
PyFunctionVariant::F2(concat_str),
// etc...
];
register_submodule("module", python, parent, functions)
Edit: There is also another way, you can use Vec<Box<dyn Any>>
for passing vector of functions.编辑:还有另一种方法,您可以使用
Vec<Box<dyn Any>>
来传递函数向量。 Read about it here在这里阅读
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.