Python中的下划线

只有一个下划线(_)是干嘛的呢?

在 Python 解释器里面,对单个下划线是有特殊的 “感情” 的,我来给你举个例子:

Python中的下划线
仔细看你会发现,_ 是有值的,这是因为在 Python 解释器里面, _ 会指向你最后一次执行的表达式。这在我们使用 Python 交互的时候常常会用到。
除此之外,我们还可以使用单个下划线来格式化变量的值,比如金额:
Python中的下划线
通过这样的表现,我们能更加易读, Python 也知道我们在表示什么。
再者,单个下划线还可以使用在循环语句中:
Python中的下划线

你常见的 __xx__

这种以两个下划线开头和结尾的命名方式,我想应该是你最常见到的了,比如我们之前说的类的初始化方法:
Python中的下划线
其实这些,我们叫它们为 “魔法函数” ,也就是说,它是 Python 内置好了的,我们可以直接拿来使用。所以你应该尽量避免做这样类似的以两个下划线开头和结尾的方式去命名。

单个下划线开头的 _xx

以单个下划线开头命名的方法或者变量,就是说明它是仅提供内部使用的。

举一个例子,我们来创建一个模块(handsomeb.py),然后在里面创建两个方法,一个以单个下划线开头命名,一个不以单个下划线开头命名:
Python中的下划线
接着我们去引用这个模块,分别执行模块中的方法:
Python中的下划线
当我们去执行 my_func() 输出 fxxkpython ,没毛病吧:
Python中的下划线
但是当我们去执行 _my_func() 的时候就不行了:
Python中的下划线
这时候它告诉我们 _my_func 没有定义,因为它只能被模块内部使用。

单个下划线结尾的 xx_

我们知道, Python 有许多关键词,比如 def、return、calss、pass 这些,它们都是有特殊的意义的,所以我们在定义变量或者方法的时候,不可以用它们来命名的,比如这样是错误的:
Python中的下划线
如果你一定要用这样的名称呢?为了区分,在它们的后面添加一个下划线:
Python中的下划线
但是不建议这样命名,有那么多名称,何必去定义关键词相关的名称呢。

两个下划线开头的命名: __xx

这种命名的方式更多的是用在类的继承,通过两个下划线开头命名的成员,可以防止被子类重写。
我们来写一个这样的 Person 类:
Python中的下划线
可以看到,在 Person 这个类里面,有两个变量,一个是 name ,一个是 age。不过 age 是以两个下划线开头命名了。

当我们去实例化这个 Person 的时候,发现 name 可以正常访问,但是 __age 无法访问了。
我们来打印一下这个对象的属性:
Python中的下划线
仔细看,name 还是 name, 但是 __age 变成了 _Person__age。

所以我们无法重写原来的 __age:
Python中的下划线
我们来打印一下这个 Son 类的属性:
Python中的下划线
可以发现,son 里面的 __age 实质上已经变成了 _Son__age。所以你要得到真正重写的值可以这样:
Python中的下划线

一个下划线+类名+两个下划线开头的命名: _classname__xx

通过上面第 5 点的解释,那么还有这么一种命名方式应该对你来说就好理解了:
Python中的下划线
你可以这样去使用它:
Python中的下划线