如何在PyO3中实现python操作符

2024-05-15 23:42:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试在rust中为我的数学库实现一个向量类。在

#[pyclass]
struct Vec2d {
    #[pyo3(get, set)]
    x: f64,
    #[pyo3(get, set)]
    y: f64
}

但我不知道如何重载标准运算符(+,-,*,/)

我尝试从std::ops实现Add trait,但没有成功

^{pr2}$

我还尝试将__add__方法添加到#[pymethods]块中

fn __add__(&self, other: & Vec2d) -> PyResult<Vec2d> {
    Ok(Vec2d{x: self.x + other.x, y: self.y + other.y })
}

但仍然不起作用。在

使用第二种方法,我可以看到方法在那里,但是python不认为它是操作符重载

In [2]: v1 = Vec2d(3, 4)
In [3]: v2 = Vec2d(6, 7)
In [4]: v1 + v2
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-08104d7e1232> in <module>()
----> 1 v1 + v2

TypeError: unsupported operand type(s) for +: 'Vec2d' and 'Vec2d'

In [5]: v1.__add__(v2)
Out[5]: <Vec2d object at 0x0000026B74C2B6F0>

Tags: 方法inselfaddget数学rustv2
1条回答
网友
1楼 · 发布于 2024-05-15 23:42:21

根据^{}文档

Python的对象模型为不同的对象行为定义了几种协议,如序列、映射或数字协议。PyO3定义了它们各自的特征。要提供特定的python对象行为,需要为结构实现特定的trait。

重要提示,每个协议实现块都必须用[pyproto]属性进行注释。在

__add____sub__等在^{}特征中定义。在

因此,您可以为您的Vec2d结构实现PyNumberProtocol,以重载标准操作。在

#[pyproto]
impl PyNumberProtocol for Vec2d {
    fn __add__(&self, other: & Vec2d) -> PyResult<Vec2d> {
            Ok(Vec2d{x: self.x + other.x, y: self.y + other.y })
   }
}

相关问题 更多 >