跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何让Python类支持反向算术运算_实现__radd__等右侧运算符

Python类默认不支持右侧算术运算,因__radd__等反向方法仅在左操作数__add__返回NotImplemented时才被调用;若抛异常或返回None,则直接报错。 Python 类默认不支持右侧算术运算(比如
1 + obj
),除非你显式实现
__radd__
等反向方法;否则会直接报
TypeError: unsupported operand type(s)
。 为什么
__radd__
不是自动调用的? Python 的算术运算有明确的调用顺序:先尝试左操作数的
__add__
,失败(返回
NotImplemented
,不是
NotImplementedError
!)后,才去查右操作数的
__radd__
。如果左操作数抛出异常或返回其他值,
__radd__
根本不会被触发。
__add__
必须显式返回
NotImplemented
(注意大小写),不能 return None 或 raise Exception 内置类型如
int
str
在不支持时也返回
NotImplemented
,所以你的类和它们混合运算才可能走到
__radd__
如果左操作数是自定义类且没实现
__add__
,Python 会直接报错,根本不会查右操作数 如何正确配对实现
__add__
__radd__
? 二者逻辑应保持一致,且
__radd__
通常只处理「左操作数无法处理当前右操作数类型」的场景。常见做法是把计算逻辑提取到私有方法中,避免重复。
class Vector: def __init__(self, x, y): self.x = x self.y = y
def _add_impl(self, other):
    if isinstance(other, Vector):
        return Vector(self.x + other.x, self.y + other.y)
    elif isinstance(other, (int, float)):
        return Vector(self.x + other, self.y + other)
    return NotImplemented

def __add__(self, other):
    result = self._add_impl(other)
    return result if result is not NotImplemented else NotImplemented

def __radd__(self, other):
    # int + Vector → 调用 Vector.__radd__
    result = self._add_impl(other)
    return result if result is not NotImplemented else NotImplemented
Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 立即学习 “ Python免费学习笔记(深入) ”;
__radd__
接收的是「左操作数」(即
1 + v
中的
1
),但方法体里它作为
other
传入逻辑函数 务必检查
isinstance(other, ...)
,别假设类型;否则
__radd__
可能被误用于不支持的类型 返回
NotImplemented
表示“我也不支持”,让 Python 继续找下一个候选(比如父类方法),而不是抛错 哪些反向方法需要成对实现? 不是所有算术方法都有反向版本。常用且需配对的是:
__radd__
__rsub__
__rmul__
__rtruediv__
__rpow__
。而
__rfloordiv__
__rmod__
__rdivmod__
等也存在,但使用频率低得多。
__rsub__
__rtruediv__
特别容易写反:注意
a - b
对应
a.__sub__(b)
,但
b - a
a.__rsub__(b)
,即
b - a == a.__rsub__(b)
,所以实现时是
other - self.x
,不是
self.x - other
没有
__req__
__rbool__
—— 比较和布尔运算不走反向协议
__rmatmul__
@
运算符)存在,但仅在需要支持矩阵乘法与标量混合时才需考虑 最容易被忽略的一点:反向方法只有在左侧对象明确放弃处理时才起作用;如果你的
__add__
返回了
None
或抛了异常,
__radd__
就永远没机会运行。

相关文章