魔法方法(或称 dunder 方法 – 来自于 double underscore)是特殊的方法,其名称以两个下划线开始和结束,例如 __init__、__str__、__add__。它们允许将自定义类的实例嵌入到 Python 的语法和行为中:定义对算术操作、比较、字符串转换、集合协议等的反应。
示例:
class Vector: def __init__(self, x, y): self.x = x self.y = y def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) def __str__(self): return f"Vector({self.x}, {self.y})" v1 = Vector(1, 2) v2 = Vector(3, 4) print(v1 + v2) # 将调用 v1.__add__(v2),返回 Vector(4, 6)
如果在自定义类中未实现
__eq__,那么实例之间将如何使用==操作符进行比较?
答案: 默认情况下,== 操作符根据身份(内存地址,类似于 is 操作符)来比较对象,如果不重写魔法方法 __eq__。
class A: pass print(A() == A()) # False,虽然对象“看上去相同”
故事
在一个需要比较图结构的项目中,没有实现 __eq__ 方法。由于在检查“节点是否已添加”时,== 操作符根据 id 而不是内容比较对象,因此得到了不正确的结果。
故事
在编写 REST API 时,通过 str(obj) 将对象序列化为字符串进行日志记录,但忘记定义 __str__。结果输出了不可读的文本 <MyObj object at 0x...>,这妨碍了问题诊断。
故事
在一个数学计算库中,仅实现了 __add__,但忘记了 __iadd__ 用于操作符 +=。因此,表达式 v += w 的表现与预期不符(创建了新对象,而没有更新旧对象),导致在复杂计算中发生内存泄漏。