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

如何在Python中实现不同类型点类的+运算符多重载(非isinstance方案)

解决方案:使用functools.singledispatchmethod实现类型感知的运算符重载

Python不会将仅类型注解不同的函数视为重载——类型注解只是提示信息,不改变函数签名,后定义的__add__会直接覆盖之前的。要实现无需isinstance()判断的跨类型点相加,可以用标准库functools提供的singledispatchmethod,它能基于参数的实际类型自动选择对应的处理逻辑。

完整改造代码

from functools import singledispatchmethod

class Point2D:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    @singledispatchmethod
    def __add__(self, other):
        raise TypeError(f"不支持Point2D与{type(other)}类型相加")

    @__add__.register
    def _(self, other: "Point2D"):
        return Point2D(self.x + other.x, self.y + other.y)

    @__add__.register
    def _(self, other: "Point3D"):
        return Point3D(self.x + other.x, self.y + other.y, other.z)

    def __repr__(self):
        return f"({self.x}, {self.y})"

class Point3D(Point2D):
    def __init__(self, x=0, y=0, z=0):
        super().__init__(x, y)
        self.z = z

    @singledispatchmethod
    def __add__(self, other):
        raise TypeError(f"不支持Point3D与{type(other)}类型相加")

    @__add__.register
    def _(self, other: "Point3D"):
        return Point3D(self.x + other.x, self.y + other.y, self.z + other.z)

    @__add__.register
    def _(self, other: "Point2D"):
        return Point3D(self.x + other.x, self.y + other.y, self.z)

    def __repr__(self):
        return f"({self.x}, {self.y}, {self.z})"

测试验证

运行以下代码:

print(Point2D(1, 2) + Point3D(0, 1, 2))  # 输出:(1, 3, 2)
print(Point3D(0, 1, 2) + Point2D(1, 2))  # 输出:(1, 3, 2)
print(Point2D(1, 2) + Point2D(3, 4))     # 输出:(4, 6)
print(Point3D(1, 2, 3) + Point3D(4, 5, 6)) # 输出:(5, 7, 9)

完全符合预期的跨类型、同类型相加需求。

核心原理

singledispatchmethod是专门为类方法设计的单分派工具:

  • 它以__add__方法的第一个非self参数(也就是other)的实际类型为匹配依据
  • 每个@__add__.register装饰的方法对应一种参数类型的处理逻辑,无需手动判断类型
  • 如果没有匹配到对应类型的实现,会触发最开始定义的基础__add__方法(这里是抛出类型错误)

注:注册的方法名称可以用下划线_或任意名称,singledispatchmethod只关注注册的类型,不关心方法名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:37:06