如何在Python中重写Rust结构体中被其他方法调用的方法?
在PyO3中让Rust父类方法调用Python子类重写的方法
核心问题在于:Rust中直接调用结构体的方法是静态绑定,完全绕开了Python的方法调度机制。当你在Rust的return_modified_value里执行self.modify_value()时,只会调用Rust impl块中定义的版本,不会去查找Python子类里重写的方法。
要解决这个问题,需要让Rust代码通过PyO3提供的Python对象接口动态调用方法,而不是直接调用静态的Rust方法。
修改后的Rust代码
use pyo3::prelude::*; #[pyclass(subclass)] pub struct ListElement { #[pyo3(get, set)] pub value_sum: f32, } #[pymethods] impl ListElement { #[new] fn new(value_sum: f32) -> Self { ListElement { value_sum } } fn return_modified_value(&mut self, py: Python<'_>) -> PyResult<f32> { // 将Rust结构体转换为Python对象引用,触发Python方法调度 let py_self = PyCell::from_mut(py, self).as_ref(py).into_py(py); // 动态调用Python端的modify_value方法 py_self.call_method0("modify_value")?; Ok(self.value_sum) } // 保留Rust默认实现(可选,子类未重写时会执行此逻辑) fn modify_value(&mut self) { self.value_sum = self.value_sum.powf(2.0); } } #[pymodule] fn my_rust_module(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::<ListElement>()?; Ok(()) }
简化后的Python代码
from my_rust_module import ListElement class PythonListElement(ListElement): def modify_value(self): self.value_sum = 3.0 * self.value_sum ple = PythonListElement(2) print(ple.return_modified_value()) # 输出6.0,符合预期
处理带参数的场景(对应你的实际需求)
如果modify_value需要接收自定义对象参数,只需调整Rust中的调用逻辑:
// Rust中修改return_modified_value方法 fn return_modified_value(&mut self, py: Python<'_>, custom_obj: &PyAny) -> PyResult<f32> { let py_self = PyCell::from_mut(py, self).as_ref(py).into_py(py); // 传递自定义对象参数调用Python方法 py_self.call_method1("modify_value", (custom_obj,))?; Ok(self.value_sum) }
Python端对应实现:
def modify_value(self, custom_obj): # 处理自定义对象的业务逻辑 self.value_sum = 3.0 * self.value_sum + custom_obj.some_attribute
关键原理
- 通过
PyCell::from_mut将Rust的&mut self转换为Python对象引用,这样就能利用Python的方法查找机制,优先调用子类重写的方法。 call_method0/call_method1等方法是PyO3提供的动态调用接口,会自动处理子类方法重写的逻辑。
内容的提问来源于stack exchange,提问作者rustbegginer
相关产品推荐
相关产品推荐

