【参考】:https://blog.csdn.net/tcx1992/article/details/80105645
开头或结尾,使用单下划线或双下划线,的变量名、函数名等命名,其对应对象在Python中往往有特殊的使用习惯或作用。
1. Python下划线用法总结
模式 |
举例 |
含义 |
特殊性 |
独立单下划线 |
_ |
有时用作临时或无意义变量的名称。也表示Python REPL中最近一个表达式的结果。 |
无,常用于占位或临时变量 |
后单下划线 |
var_ |
按约定使用以避免与Python关键字的命名冲突。 |
无 |
前单下划线 |
_var |
命名约定,仅供内部使用。通常不会由Python解释器强制执行(通配符导入除外),只作为对程序员的提示。 |
基本无,除了from xx import *通配符导入时 |
前后双下划线 |
__var__ |
表示Python语言定义的特殊方法。避免在你自己的属性中使用这种命名方案。 |
无,python官方保留使用,个人避免使用,造成与官方方法或属性名冲突 |
前双下划线 |
__var |
当在类上下文中使用时,触发“名称修饰”。由Python解释器强制执行。 |
python强制对其名称修饰 |
单下划线不特殊,前后双下划线留给官方使用,前双下划线自动名称修饰。
2. 独立单下划线 _
与普通变量名无异,因_无字面含义,故常用于临时变量或占位变量,从而避免设置过多无用变量名。
# 临时变量
>>> for _ in range(3):
print("Hello")
Hello
Hello
Hello
#占位变量, 如下面用元组对一组变量赋值
>>> car = ('red', 'auto', 12, 3812.4)
>>> color, _, _, mileage = car
>>> color
'red'
>>> _
12
>>> mileage
3812.4
3. 后单下划线 var_
普通变量名或函数名,无特殊含义,只是通过Python保留字加下划线的方式,避开了保留字无法做命名的限制,又可以达到关键字的释义效果。
>>> try = "Try my best"
SyntaxError: invalid syntax
>>> try_ = "Try my best"
>>> try_
'Try my best'
>>> def sum(in):
SyntaxError: invalid syntax
>>> from functools import reduce
>>> def mysum(in_):
out = reduce(lambda x,y:x+y,in_)
print(out)
>>> mysum([1,2,3])
6
4. 前单下划线 _var
相当于普通变量名或函数名,类的内部方法名、属性名,或函数的内部变量名,常用此种命令格式。
但这只是一种约定的命名规范,python并不强制将其作为内部方法或内部属性,仍可以从实例化后的对象使用这些方法或属性。
唯一的特殊情况时,对于*.py文件作为模块使用通配符form my_module import *导入时,python不会导入有前导下划线的函数,不用通配符import my_module导入时则无影响。
>>> class account:
def __init__(self,name):
self.username = name
self._password = "default_pswd"
>>> a1 = account("zhang3")
>>> a1.username
'zhang3'
>>> a1._password
'default_pswd'
cat my_module.py
# This is my_module.py:
def external_func():
return 123
def _internal_func():
return 321
>>> from my_module import *
>>> external_func()
123
>>> _internal_func()
NameError: "name '_internal_func' is not defined"
>>> import my_module
>>> my_module.external_func()
123
>>> my_module._internal_func()
321
5. 前后双下划线 __var__
与普通命名无异,但不建议个人使用,因为python语言自身内置有大量的属性名和方法名,使用了前后双下划线的命名方式。个人代码使用前后双下划线命名,可能造成与python语言内置对象的命名冲突。
# 个人可使用,但不建议
>>> class myclass:
def __init__(self):
self.__myvar__ = 123
def __myfunc__(self):
print("Hello")
>>> a1.__myvar__
123
>>> a1.__myfunc__()
Hello
# 可能与python语言内置属性或方法命名冲突,导致报错,如下面的__class__
>>> dir(a1)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__myfunc__', '__myvar__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> class myclass:
def __init__(self):
self.__myvar__ = 123
self.__class__ = "xxx"
def __myfunc__(self):
print("Hello")
>>> a1 = myclass()
Traceback (most recent call last):
File "<pyshell#69>", line 1, in <module>
a1 = myclass()
File "<pyshell#68>", line 4, in __init__
self.__class__ = "xxx"
TypeError: __class__ must be set to a class, not 'str' object
6. 前双下划线 __var
开头双下划线的命名最为复杂,python会对其进行“名称修饰”转换,需要特别小心使用。
名称修饰,即将一个类(如myclass)中,以双下划线开头的属性名或函数名(如__myvar、__myfunc,非双下划线结尾),在实例化为对象时,将其名称前面加上单下划线和类名(如_myclass__myvar、_myclass__myfunc)。
>>> class myclass:
def __init__(self):
self.myvar = 1
self._myvar = 2
self.__myvar = 3
def myfunc(self):
print("Hello 1")
def _myfunc(self):
print("Hello 2")
def __myfunc(self):
print("Hello 3")
>>> a1 = myclass()
>>> dir(a1)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_myclass__myfunc', '_myclass__myvar', '_myfunc', '_myvar', 'myfunc', 'myvar']
可以看到实例化的对象中,已经没有原来双下划线开头的属性和方法(__myvar、__myfunc),他们被进行了名称修饰(变为了_myclass__myvar、_myclass__myfun)。
>>> a1.myvar
1
>>> a1._myvar
2
>>> a1.__myvar
Traceback (most recent call last):
File "<pyshell#80>", line 1, in <module>
a1.__myvar
AttributeError: 'myclass' object has no attribute '__myvar'
>>> a1._myclass__myvar
3
>>> a1.myfunc()
Hello 1
>>> a1._myfunc()
Hello 2
>>> a1.__myfunc()
Traceback (most recent call last):
File "<pyshell#84>", line 1, in <module>
a1.__myfunc()
AttributeError: 'myclass' object has no attribute '__myfunc'
>>> a1._myclass__myfunc()
Hello 3
可以使用名称修饰后的属性或方法名,来访问原属性或方法。