Python 特殊方法

说明 Python 特殊方法如何把对象接入运算符、容器、迭代器、上下文管理器等语言级协议。

#type / concept #status / growing #resource / python #tech / lang / python

[!info] related notes

Python 特殊方法

一句话定义

特殊方法是形如 __xxx__ 的协议钩子,Python 解释器会在运算符、内建函数或特定语法场景下自动调用它们,从而让自定义对象表现得像内建类型一样自然。

核心机制 / 工作原理

1. 特殊方法的本质是“语言协议入口”

当你写:

  • len(obj)
  • obj1 + obj2
  • for x in obj
  • with obj as resource

Python 并不是在做魔法,而是在尝试调用对象对应的特殊方法,例如:

  • __len__
  • __add__
  • __iter__
  • __enter__ / __exit__

所以特殊方法的价值在于:让你的对象接入 Python 的统一调用协议。

2. 常见协议大致可以分成几类

  • 构造与表示:__new____init____repr__
  • 容器与迭代:__len____getitem____iter__
  • 运算符:__add____eq__
  • 可调用对象:__call__
  • 上下文管理:__enter____exit__

你不需要一次记完所有名字,但要先建立一个观念:这些不是零散技巧,而是 Python 数据模型的一部分。

3. 特殊方法让“对象行为”能被统一消费

如果一个对象实现了 __iter__,它就能被 for 循环消费;如果实现了 __len__,它就能被 len() 读取长度。也就是说,调用方往往不关心“你是不是某个具体类”,只关心“你有没有协议要求的行为”。

这也正好和 鸭子类型 的思路衔接起来。

最小例子 / 最小场景

class Vector:
    def __init__(self, x: float, y: float):
        self.x = x
        self.y = y

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

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

    def __len__(self):
        return int((self.x ** 2 + self.y ** 2) ** 0.5)


v1 = Vector(1, 2)
v2 = Vector(3, 4)

print(v1 + v2)  # Vector(4, 6)
print(len(v1))  # 2

这里同一个类同时接入了“加法协议”“字符串表示协议”“长度协议”。

边界与易混淆点

  1. 不是所有双下划线名字都能随便自创;只有 Python 约定好的协议名才会被解释器识别。
  2. 特殊方法通常应该通过语法或内建函数触发,例如用 len(obj) 而不是直接手写 obj.__len__()
  3. 特殊方法应该服务于对象语义,而不是为了“看起来高级”把普通业务逻辑硬塞进 dunder 方法里。
创建于 2026/5/20 更新于 2026/5/27