fds*_*dsa 11 python cpython object rust
我正在使用pyo3rust crate (version 0.11.1) 以便将 rust 代码移植到 cpython (version 3.8.2) 代码中。我创建了一个名为类my_class,定义了以下功能:new,__str__,和__repr__。
TL;DR:该
__str__函数存在于使用 pyo3 crate 从 rust 移植的类上,但在使用时不会打印print(obj),而是必须编写print(obj.__str__())
该my_class定义是在这里:
use pyo3::prelude::*;
#[pyclass]
struct my_class {
#[pyo3(get, set)]
num: i32,
#[pyo3(get, set)]
debug: bool,
}
#[pymethods]
impl my_class {
#[new]
fn new(num: i32, debug: bool) -> Self {
my_class {num, debug}
}
fn __str__(&self) -> PyResult<String> {
Ok(format!("[__str__] Num: {}, Debug: {}", self.num, self.debug))
}
fn __repr__(&self) -> PyResult<String> {
Ok(format!("[__repr__] Num: {}, Debug: {}", self.num, self.debug))
}
}
#[pymodule]
fn pymspdb(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<my_class>()?;
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
我构建它(进入发布模式),并使用以下代码测试代码:
from my_module import my_class
def main():
dsa = my_class(1, True)
print(dsa)
print(dsa.__str__())
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
运行测试 python 代码时,我得到以下输出:
<my_class object at 0x7fb7828ae950>
[__str__] Num: 1, Debug: true
Run Code Online (Sandbox Code Playgroud)
现在我已经想到了可能的解决方案。一种解决方案可能是 pyo3 rust crate 实际上充当代理,为了将类移植到 python 中,可能会实现某种对象,将所有操作转移到移植类。所以它可能不会实现自己的,__str__因此没有给我我想要的。我想到的第二个可能的解决方案是我可能没有正确重载__str__函数,因此当 python 尝试使用打印函数时,它不会访问正确的函数,只是执行默认行为。
感谢您阅读到目前为止,希望我能找到答案,因为我没有在网上找到任何相关内容。
编辑:此问题已解决,正确代码如下:
<my_class object at 0x7fb7828ae950>
[__str__] Num: 1, Debug: true
Run Code Online (Sandbox Code Playgroud)
我很确定这是因为您需要通过PyObjectProtocoltrait来实现这些方法。
许多 Python__magic__方法对应于类型对象内存布局中的C 级函数指针插槽。C 中实现的类型需要在槽中提供函数指针,Python 会自动生成一个方法来包装该指针以供显式方法调用。在 Python 中实现的类型将自动插入委托给魔术方法的函数指针。
Python 内部通常会寻找函数指针而不是相应的魔法方法,如果 Python 没有找到函数指针,它将表现为该方法不存在。这就是为什么,例如,您必须使用#[new]标记构造函数而不是实现__new__静态方法。
__str__并且__repr__也对应于函数指针——特别是,tp_str和tp_repr。如果您只是尝试将它们实现为常规方法,pyo3 将不会生成所需的函数指针。PyObjectProtocol是要通过的 pyo3 接口。
| 归档时间: |
|
| 查看次数: |
456 次 |
| 最近记录: |