0. 汇总
在不同场合下,下划线有不同含义:比如_var
表示内部变量;__var
表示私有属性;__var__
表示魔术方法;
这里总结下 python 中用到下划线的场景
_
用于临时变量var_
用于解决命名冲突问题_var
用于保护变量__var
用于私有变量__var__
用于魔术方法
1. _ 临时变量
单下划线一般用于表示临时变量,在REPL、for循环和元组拆包等场景中比较常见。
REPL(交互式命令行)中,_
保存的是上一次计算的非 None 的结果
>>> "hello, world"
'hello, world'
>>> _
'hello, world'
>>> 10 + 5
15
>>> _
15
在 for
循环中,_
表示没有意义的变量,相当于占位符,只是占了个位子,并不需要循环出来的内容
# 我们来打印十次 hello world
>>> for _ in range(10): # 在循环体里面,我们用不到 range(10) 中每次的变量,所以用 _ 来占位
... print("hello, world")
...
hello, world
hello, world
hello, world
hello, world
hello, world
hello, world
hello, world
hello, world
hello, world
hello, world
在拆包中,我们也会用到 _
,例如下面的场景,我们只需要其中的一部分信息,并不全需要
>>> person_info = ("nancy", 20, "Australia")
>>> name, _, addr = person_info # 这里我们只关注 name 和 address 所以 age字段用 _ 占位
>>> name
'nancy'
>>> addr
'Australia'
>>> name, *_ = person_info # 如果中间需要忽略的内容过多,可以用通配符*来解决
>>> name
'nancy'
_
还可用来分隔大数值的数字,用来表达可读性更高
>>> num = 1_111_999_000_000
>>> num
1111999000000
>>>
2. args_ 命名冲突
变量后面加一个下划线。主要用于解决命名冲突问题,编程中遇时Python保留的关键字时,需要临时创建一个变量的副本时,都可以使用这种机制。
>>> id_ = 1
>>> id_
1
以上代码中出现的id
是Python的保留关键字,直接使用虽然在赋值变量的时候不会报错,但是并不建议这样命名。使用下划线后缀的方式解决了这个问题。
3. _var 保护变量
在变量名前面加_
是为了保护变量,如函数、方法或者属性。
在使用 from xxx import *
的时候,前缀下划线的变量,方法,属性不会被导入,这是一种保护机制。当然, 使用 __all__
可以破坏这种规则,详见这篇文章:魔法方法 all
4. __var 私有属性
在变量名前面加两个 __
,在定义类的时候可以将变量、方法变为私有方法
class Person(object):
def __init__(self):
self.name = "default"
self._age = 20
self.__addr = "Australia"
def say(self):
print(f'name is {self.name}')
print(f'age is {self._age}')
print(f'addr is {self.__addr}')
if __name__ == '__main__':
p = Person()
p.say()
print(p.name)
print(p._age)
print(p.__addr)
我们来看下输出结果,发现通过实例 p
访问不到 __addr
这个属性,那么这个属性又为什么访问不到呢?
name is default
age is 20
addr is Australia
default
20
Traceback (most recent call last):
File "/Users/nancy/Desktop/cctester_code/demo.py", line 24, in <module>
print(p.__addr)
AttributeError: 'Person' object has no attribute '__addr'
原来双下划线,被 Python 的私有属性机制改写成了这个样子, _Person__addr
,一个单下划线加类名加私有属性。其实 Python 中的私有属性并不是真正的访问不到,我们可以通过 _Person__addr
访问到私有属性
print(vars(p))
# Output
{'name': 'default', '_age': 20, '_Person__addr': 'Australia'}
print(p._Person__addr)
# Output
Australia
5. def 魔法方法
变量前面两个下划线,后面两个下划线。这是Python当中的魔术方法,一般是给系统程序调用的。例如
- 上例中的
__init__
就是类的初始化魔术方法 - 支持
len
函数的__len__
方法 - 支持上下文管理器协议的
__enter__
和__exit__
方法 - 支持迭代器协议的
__iter__
方法 - 支持格式化显示的
__repr__
和__str__
方法等等
Python 中默认的魔法方法还有很多,可以在官方文档中查看。
总结
总之,下划线在Python当中应用还是很广泛的,甚至可以说Python对下划线有所偏爱。
_
常用于临时变量,在REPL,for循环,元组拆包中得到了广泛应用args_
用于解决命名冲突问题,使用时比较简单易懂的_var
对变量的保护,只是一种脆弱的保护,更多依靠程序员的约定__var
用于私有变量,借助改写机制支持,已经支持了私有变量,但是仍然存在漏洞__def__
魔法方法,进行了一个简单的介绍,魔术方法较多,这里就不深入介绍了