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

Python类__add__方法返回类实例与返回元组的区别是什么

Python自定义类__add__方法两种返回写法的差异

写法1:返回Point类构造的实例

对应实现代码:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.coord = (self.x, self.y)

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

p1 = Point(3, 5)
p2 = Point(7, -2)
print(p1+p2)    # 输出默认格式:<__main__.Point object at 0x000001A2DAEF3E20>

这个写法的本质是:将两个点坐标相加得到的新x、y值作为入参,调用Point类的构造方法,生成一个全新的Point类型实例作为加法运算的返回值。
这个返回值和你手动创建的p1、p2是完全相同的自定义类型,自带x、y、coord属性,也支持继续调用Point类的所有方法、和其他Point实例做算术运算。
打印时出现带内存地址的默认字符串,只是因为Point类没有自定义__repr__/__str__字符串表示方法,Python回退到了默认的对象输出格式,和返回值本身的正确性无关。只要在类中补充如下方法,打印时就能直接输出可读的坐标:

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

补全后再执行print(p1+p2)就会输出Point(10, 3),不会再显示内存地址。


写法2:直接返回逗号分隔的计算值

对应修改后的__add__实现:

def __add__(self, other):
    return self.x + other.x, self.y + other.y

这个写法的本质是:Python会自动将逗号分隔的多个返回值打包成原生tuple元组类型返回,这个返回值根本不是Point类的实例,只是一个存储了两个数字的普通元组。
打印时直接输出(10, 3),是因为Python原生元组类型自带默认的格式化字符串实现,不需要额外写方法。但这个返回值完全丢失了Point类型的所有能力:它没有coord属性,不能调用Point类定义的方法,也无法继续和其他Point实例做加法运算——它只是一个存了两个数的通用容器,没有“二维点”的语义。


两种写法的核心差异

  • 类型本质不同:第一种返回的是Point自定义类实例,符合“两个点相加结果仍然是点”的运算逻辑,和Python内置类型的运算规则一致(比如两个整数相加结果仍是整数、两个列表相加结果仍是列表);第二种返回的是原生元组类型,只是碰巧存储了两个坐标数值,不具备点的类型属性。
  • 扩展能力不同:第一种返回值可以直接参与后续所有Point类型支持的操作,适合面向对象的场景扩展;第二种返回值只能作为通用二元序列使用,无法承接自定义类型的后续逻辑。
  • 打印表现差异:第一种默认输出内存地址是缺少字符串表示方法导致的,补全对应方法即可解决,不属于写法错误;第二种直接输出元组格式是原生类型的内置特性,和业务语义无关。

实际开发中做自定义类型的运算符重载时,标准做法就是返回同类型的新实例,保证运算前后类型的一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:01:15