使用PyO3在Rust中调用Python类时出现属性查找错误的问题
问题:在Rust中通过PyO3调用Python类时出现属性找不到的错误
我尝试完成一项简单任务:在Rust中处理Python类,包括实例化类、执行操作并访问其成员。查阅了大量PyO3和cpython文档,但它们大多介绍的是从Python调用Rust的场景。
为何以下代码无法找到属性?
Python端代码
class Vehicle: def __init__(self) -> None: self.speed = 0 def increase(self): self.speed += 1 def get_speed(self): return self.speed
Rust端代码
extern crate pyo3; use pyo3::prelude::*; fn main() -> PyResult<()> { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let builtins = PyModule::import(py, "vehicle")?; builtins.getattr("increase")?.call0()?; println!("{}", builtins.getattr("get_speed")?.call0()?); Ok(()) }) }
运行错误输出
Error: PyErr { type: <class 'AttributeError'>, value: AttributeError("module 'vehicle' has no attribute 'increase'"), traceback: None } error: process didn't exit successfully: `target\debug\test_ffi.exe` (exit code: 1)
预期输出
1
问题原因与修复方案
问题原因
你直接在vehicle模块对象上调用increase和get_speed方法,但这两个方法是Vehicle类的实例方法,并非模块的直接属性。模块中仅包含Vehicle这个类定义,没有直接暴露这两个方法,因此会触发AttributeError。
修复后的Rust代码
extern crate pyo3; use pyo3::prelude::*; fn main() -> PyResult<()> { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // 1. 导入vehicle模块 let vehicle_module = PyModule::import(py, "vehicle")?; // 2. 从模块中获取Vehicle类 let vehicle_class = vehicle_module.getattr("Vehicle")?; // 3. 实例化Vehicle类(调用__init__方法) let vehicle_instance = vehicle_class.call0()?; // 4. 在实例上调用increase方法 vehicle_instance.getattr("increase")?.call0()?; // 5. 调用get_speed方法并打印结果 let speed = vehicle_instance.getattr("get_speed")?.call0()?; println!("{}", speed); Ok(()) }) }
说明
修改后代码先获取Vehicle类并实例化,再在实例对象上调用对应的方法,运行后会输出预期的1。
内容的提问来源于stack exchange,提问作者mbfernan
相关产品推荐
相关产品推荐

