You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python运算符MRO:子类为右操作数时优先调用__rmul__而非__mul__

为什么子类继承父类时,*运算符会先调用右操作数的__rmul__?

你的观察完全正确,这种反直觉的调用顺序是Python运算符分发机制中子类优先的特殊规则导致的,只在右操作数(RHS)是左操作数(LHS)的子类时触发。

核心逻辑

Python的运算符分发(比如*对应的__mul__/__rmul__)在处理继承关系时,会优先给子类机会处理跨类操作:

  • 当计算LHS * RHS时,如果type(RHS)是type(LHS)的子类(即你的例子中Vector继承自Matrix),Python会先尝试调用RHS.__rmul__(LHS),而非常规的先调用LHS.__mul__(RHS)。
  • 只有当RHS.__rmul__返回NotImplemented时,才会回退到调用LHS.__mul__(RHS)。
  • 如果两者都返回NotImplemented,就会抛出TypeError。

对应你的例子分析

执行matr * vec时:

  1. 因为vec是Matrix的子类实例,Python优先调用vec.__rmul__(matr),输出Vector.__rmul__(⋯),该方法返回NotImplemented。
  2. 接着调用matr.__mul__(vec),输出Matrix.__mul__(⋯),同样返回NotImplemented。
  3. 最终抛出TypeError,提示不支持该操作数类型。

常规情况(无继承)

如果Vector不继承Matrix,Python会按你预期的顺序执行:先调用matr.__mul__(vec),返回NotImplemented后再调用vec.__rmul__(matr)。

这种设计是为了让子类可以自定义与父类的交互逻辑——比如如果Vector的__rmul__能处理和Matrix的乘法,就可以直接返回结果,不需要父类的方法介入。

内容的提问来源于stack exchange,提问作者geometrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:52:41