You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 11:27:41