python 的 dunder name和 sunder name
Python 社区里,对名字中的下划线有一套约定术语:
| 形式 | 名称 | 例子 |
|---|---|---|
name |
普通名称 | value |
_name |
single leading underscore | _cache |
name_ |
single trailing underscore | class_ |
__name |
double leading underscore | __value |
__name__ |
dunder name | __init__ |
_name_ |
sunder name | _missing_ |
其中:
__dunder___sunder_
主要出现在:
- Python 内部协议
- 元编程
Enumdataclasstyping- 解释器保留接口
一、什么是 dunder name
dunder =
double underscore
即:
__name__
这种:
-
前后各两个下划线
-
又叫:
- magic method
- special method
典型例子
__init__
__new__
__call__
__iter__
__len__
__dict__
__class__
二、dunder 的意义
这是:
Python 语言级协议接口
例如:
len(x)
实际上调用:
x.__len__()
运算符也是
a + b
本质:
a.__add__(b)
for循环
for x in obj:
本质:
iter(obj)
→ obj.__iter__()
所以 dunder 本质是:
Python 解释器保留协议名
用于:
- 运算符重载
- 对象模型
- 容器协议
- 上下文管理
- async协议
- descriptor协议
- 元类协议
等等。
三、dunder 有两个重要特点
1. 是解释器保留空间
你最好不要乱发明:
__myfunc__
因为未来 Python 可能占用。
PEP 明确建议:
用户代码不要随意定义新的 dunder 名字。
2. 由解释器隐式调用
例如:
obj[0]
其实:
obj.__getitem__(0)
所以:
- dunder 是语言协议入口
- 不是普通方法
四、什么是 sunder name
sunder =
single underscore
即:
_name_
特点:
- 前后各一个下划线
- 中间是名字
五、sunder 是“库内部保留协议”
不像 dunder 属于解释器。
sunder 更多是:
标准库/框架保留命名空间
最典型:
Enum
来自 Python 的 enum 模块。
Enum 大量使用 sunder
例如:
_missing_
_generate_next_value_
_ignore_
六、为什么 Enum 用 sunder 而不用 dunder
因为:
- dunder 是解释器级别协议
- Enum 只是标准库
它不能污染 Python 语言层。
因此:
_missing_
表示:
“Enum框架保留接口”
而不是:
“Python解释器协议”
七、一个典型例子:missing
from enum import Enum
class Color(Enum):
RED = 1
@classmethod
def _missing_(cls, value):
return cls.RED
现在:
Color(999)
不会报错,而会:
Color.RED
因为:
EnumMeta
内部会调用:
_missing_
八、dunder vs sunder 本质区别
| 对比 | dunder | sunder |
|---|---|---|
| 形式 | __x__ |
_x_ |
| 含义 | 解释器协议 | 库协议 |
| 谁调用 | Python VM | 框架/库 |
| 是否语言级 | ✅ | 🚫 |
| 是否官方保留 | 强保留 | 弱保留 |
| 用户能否发明 | 不建议 | 更不建议冲突 |
浙公网安备 33010602011771号