Python类默认不支持右侧算术运算,因__radd__等反向方法仅在左操作数__add__返回NotImplemented时才被调用;若抛异常或返回None,则直接报错。
Python 类默认不支持右侧算术运算(比如
),除非你显式实现
等反向方法;否则会直接报
。
为什么
不是自动调用的?
Python 的算术运算有明确的调用顺序:先尝试左操作数的
,失败(返回
,不是
!)后,才去查右操作数的
。如果左操作数抛出异常或返回其他值,
根本不会被触发。
必须显式返回
(注意大小写),不能 return None 或 raise Exception
内置类型如
、
在不支持时也返回
,所以你的类和它们混合运算才可能走到
如果左操作数是自定义类且没实现
,Python 会直接报错,根本不会查右操作数
如何正确配对实现
和
?
二者逻辑应保持一致,且
通常只处理「左操作数无法处理当前右操作数类型」的场景。常见做法是把计算逻辑提取到私有方法中,避免重复。
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
下载
立即学习
“
Python免费学习笔记(深入)
”;
接收的是「左操作数」(即
中的
),但方法体里它作为
传入逻辑函数
务必检查
,别假设类型;否则
可能被误用于不支持的类型
返回
表示“我也不支持”,让 Python 继续找下一个候选(比如父类方法),而不是抛错
哪些反向方法需要成对实现?
不是所有算术方法都有反向版本。常用且需配对的是:
、
、
、
、
。而
、
、
等也存在,但使用频率低得多。
和
特别容易写反:注意
对应
,但
是
,即
,所以实现时是
,不是
没有
或
—— 比较和布尔运算不走反向协议
(
运算符)存在,但仅在需要支持矩阵乘法与标量混合时才需考虑
最容易被忽略的一点:反向方法只有在左侧对象明确放弃处理时才起作用;如果你的
返回了
或抛了异常,
就永远没机会运行。
1 + obj__radd__TypeError: unsupported operand type(s)__radd____add__NotImplementedNotImplementedError__radd____radd____add__NotImplementedintstrNotImplemented__radd____add____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__radd__1 + v1otherisinstance(other, ...)__radd__NotImplemented__radd____rsub____rmul____rtruediv____rpow____rfloordiv____rmod____rdivmod____rsub____rtruediv__a - ba.__sub__(b)b - aa.__rsub__(b)b - a == a.__rsub__(b)other - self.xself.x - other__req____rbool____rmatmul__@__add__None__radd__