Python 中的下划线 _ 有 5 种以上不同身份,它既不是摆设,也不是普通的变量名,而是语言层面和社区约定共同赋予的特殊符号。下面为你详细拆解。
一、交互式解释器中:记住上一次结果
在 Python 交互环境(REPL)中,_ 自动保存 上一条表达式 的返回值。
>>> 3 + 5
8
>>> _ * 2
16
>>> result = _ + 1
>>> result
17
注意:只在交互环境生效,.py 文件中无此功能。
二、作为“一次性”变量:占位符
当你需要循环但用不到循环变量时,用 _ 表示“这个值不重要”。
for _ in range(5):
print("Hello")
# 解包时忽略某个值
a, _, b = (1, 2, 3)
print(a, b) # 1 3
# 忽略多个值(Python 3.x)
first, *_, last = [10, 20, 30, 40, 50]
print(first, last) # 10 50
三、国际化翻译(I18N):gettext 的别名
在需要支持多语言的项目中,_ 常作为 gettext.gettext() 的简写。
import gettext
gettext.install('myapp')
print(_("Hello, World!")) # 根据语言环境输出翻译后的字符串
这不是语法特性,而是社区约定。
四、数字字面量中的视觉分隔符(Python 3.6+)
下划线可出现在数字中间,提高可读性(解释器会忽略它)。
million = 1_000_000
hex_val = 0xFF_FF_FF_00
bin_val = 0b_1101_1010
print(million) # 1000000
五、命名约定:私有/保护属性的标志
5.1 单前缀下划线 _var
约定:表示“内部使用”(protected),类外部可访问,但不应直接使用。
classMyClass:
def__init__(self):
self._internal = 42
obj = MyClass()
print(obj._internal) # 能运行,但不推荐
from module import * 会 忽略 以 _ 开头的名称。
5.2 双前缀下划线 __var(名称修饰)
Python 会改写属性名,避免子类意外覆盖。
classParent:
def__method(self):
print("parent")
classChild(Parent):
def__method(self):
print("child")
c = Child()
c.__method() # 报错:找不到
print(dir(c)) # 看到 _Parent__method 和 _Child__method
机制:__method 变成 _ClassName__method。
5.3 双前缀双后缀 __var__(魔法方法)
Python 保留系统定义的方法,如 __init__、__str__、__len__。
classDemo:
def__init__(self):
pass# 这是魔法方法,不是私有属性
规则:不要自己创造 这种形式的名称。
六、作为变量名:避免与关键字冲突
虽然通常不推荐,但可以临时用作变量名。
_ = 5
print(_) # 5
list_ = [1,2,3] # 避免与内置 list 冲突
七、模式匹配(Python 3.10+ match-case)中的通配符
在 match 语句中,_ 表示“匹配任何值,但不绑定”。
match value:
case 0:
print("zero")
case _:
print("other")
总结速查表
| | |
|---|
_ | | for _ in range(5) |
1_000 | | a = 10_000 |
_func | | def _internal() |
__func | | class A: __x |
__func__ | | __init__ |
_ | | print(_('ok')) |
_ | | case _: |
一句话总结:
一个下划线是“约定”,两个下划线是“改名”,两边下划线是“魔法”,单独下划线是“无所谓”。