下划线 _
是很神奇的一个符号,在Python里有很多特殊作用。
1. 表示刚才输出的内容
用下划线表示最近一次输出的内容,这个在很多教程问答中出现,请认真看下面这个:
使用 python3
命令进入python的解释器状态:
第一行输入
s='a,b,c,d'
然后就回车第二行输入_
,报错notdefined
未定义,说明刚才什么也没输出(不是吗?)。然后输入单个的
s
回车,输出了字符串'a,b,c,d'
,然后再执行s.split(',')
用逗号分割成为列表,成功!然后输入
a=99
,再换行输入_
,得到的仍然是刚才输出的列表(不是字符串啦!)再输入
a
,回车输出99
,这也把'_'变成了99
,然后+1
就会累加上去。后来我们又创建了列表
c
,并输出它,也就指定到了_
,并且可以使用_[0:1]
取得第一个元素,说明下划线不仅仅可以表示输出的字符串和数字,还可以是更复杂的东西。
注意:这种用法只能在命令行中使用,禁止在
.py
文件或者Notebook
中使用。
2. “我不在乎这个东西”
下划线还可以当做毫无意义的占位符号,比如 for
循环的格式是 forninrange(0,100):
这里的 n
有些时候根本没有用,但又不能省略,那么就可以用下划线鄙视它一下:
for _ in range(10):
print('哈')
哈
哈
哈
哈
哈
哈
哈
哈
哈
哈
这里只是大笑十声,那么如果用 n
也毫无用处,但是下面这个情况就还是需要 n
的:
for n in range(10):
print('第'+str(n+1)+'声大笑')
第1声大笑
第2声大笑
第3声大笑
第4声大笑
第5声大笑
第6声大笑
第7声大笑
第8声大笑
第9声大笑
第10声大笑
这个用法可以扩展到元组构成的列表:
li=[('a',99),('b',100)]
for _,v in li:
print(v)
99
100
输出 99
和 100
。如果变成 forv,_inli:
就会输出 a
和 b
。如果变成 forvinli
就会输出两个完整的元组 ('a',99)
和 ('b',100)
。
还有一些其他情况也可以用下划线表示占位:
a=(101,102,103,104,105)
x,_,z,_,_=a
print(x,z)
101 103
直接创建 x
和 z
两个变量,输出 101
和 103
,我们不在乎其他的。下面是更厉害的占位:
a = (101, 102, 103, 104, 105)
x, *_, m = a
print(x, m)
101 105
星号是乘法,在这里就把中间的几个都占位了,输出 101
和 105
。
3. _abc单下划线开头,表示私有不被导出
单个下划线开头的名称只能在当前文件使用,不能导出到其他文件调用。比如下面的 gongkai
对象可以在被别的文件 import
这个文件后调用,但 _siyou
却不能被使用:
#a.py文件
class gongkai():
_hide=99
vis=100
def _hideMethod(self):
print('...')
def visMethod(self):
print('>>',self._hide,self.vis)
class _siyou():
vv=88
#b.py文件
from a import *
print(gongkai)
c=gongkai()
print(c._hide,c.vis)
c.visMethod()
#print(_siyou)
把 a.py
和 b.py
放在一个文件,命令行进入这个文件夹,运行 python3 b.py
会发现gongkai的都能正常显示, _hide
的下划线根本没用,一样可以输出。但是整个 _siyou
都不能使用了。
下划线开头的顶级名称会被 import
禁用。但其他的下划线开头的名称作为私有,这就只是一种惯例而已。
但其实python根本不存在私有这个概念的,即使上面的
__siyou
也可以通过fromaimport__siyou
正常导入,只是*
星号会忽略它。如果你再a.py
里面添加一行__all__=['_siyou']
那么import*
之后,_siyou
可以用,gongkai
却不可以用了。
4. abc_下划线结尾,只是避免和系统自带关键字重名
这也是一个惯例,比如不能 from=100
因为 from
是关键字,只能改为 from_=100
(如果你非要坚持用from这个词的话)。
再比如下面这个 s
类是对 str
字符串的扩展,避免了 split
命名重复:
class s(str):
def split_(self):
return 100
aa=s('a,b,c')
print(aa.split_(),aa.split(','))
100 ['a', 'b', 'c']
输出 100
和 ['a','b','c']
。
5. __abc双下划线开头,表示碾压子类同样的名称
上面我们用 s(str)
扩展了 str
类,避免了 split
方法混淆,但如果真的混淆了,那么该听谁的呢?如果在 classa
里面使用了双下划线的名称开头,那么不管以后怎么扩展,都是它说了算,比如:
class A:
__v=100
v=200
def p(self):
print(self.__v,self.v)
class B(A):
__v=99
v=199
b=B()
b.p()
100 199
输出 100
和 199
。 v
被子类 B
覆盖了,但 A
把子类的 __v
给碾压了。
6. __abc__双下划线开头又结尾,表示这是系统需要的功能
这样的名称一般不会用到,但也不要去修改。比如 __init__
用来初始化类。
7. gettext的_是一个用于i18n/l18n的方法
i18n
就是 Internationalization
(i+18个字母+n组成)国际化; l
就是 Localization
本地化。如果你 importgettext
那么就会有下划线这个方法,其实就是 gettext.gettext
的缩写。
8. 1_000_000分割数字,相当于数字中的千分位逗号
a = 1_000_000
a
1000000
a = 1_0_0
a
100
1_000_000
就是100万, 1_0_0
就是100。
以上就是本文的全部内容,希望对大家的学习有所帮助。如果觉得文章不错,动手转发支持一下哦!
感谢您的阅读!想了解更多有关技巧,请关注我的微信公众号“R语言和Python学堂”,同时也欢迎大家积极投稿,促进交流。
我的专栏:
简书:https://www.jianshu.com/u/981ba7d6b4a6