下划线的分类解释
参考:https://blog.csdn.net/tcx1992/article/details/80105645
前面放一个下划线:_var
后面放一个下划线:var_
前面放二个下划线:__var
前面和后面各放二个下划线:__var__
单下划线:_
1、在变量名或方法名的前面放置单个下划线 【提示变量或方法仅供内部使用】
只是对程序员的一个提示:意味着Python社区一致认为它应该是什么意思,但程序的行为不受影响。
下划线前缀的含义是告知其他程序员:以单个下划线开头的变量或方法仅供内部使用。该约定在PEP 8中有定义。
这不是Python强制要求的写法,是程序员们自己造出来的方式,方便理解而已。
class Test: def __init__(self): self.foo = 11 self._bar = 23 t = Test() print(t.foo) print(t._bar) # 如果是在Pycharm中,会提示_bar是一个保护变量,但其实并不影响我们的访问
结果:
11
23
注意:
如果使用通配符(*)从模块中导入所有名称,则Python不会导入带有前导下划线的名称(除非模块定义了覆盖此行为的__all__列表)。
from module import *
_inner() # 错误
与通配符导入不同,常规导入不受前导单个下划线命名约定的影响。
import module
module._inner() # 正确
2、末尾放置单个下划线 【避免关键字冲突】
有时候,一个变量的最合适的名称已经被一个关键字所占用。 因此,像class或def这样的名称不能用作Python中的变量名称。 在这种情况下,你可以附加一个下划线来解决命名冲突。
def make_object(name, class): SyntaxError: "invalid syntax" def make_object(name, class_): ... pass
总之,单个末尾下划线(后缀)是一个约定,用来避免与Python关键字产生命名冲突。 PEP 8解释了这个约定。
3、前面放置二个下划线 【避免命名冲突】
双下划线前缀会导致Python解释器重写属性名称,以避免子类中的命名冲突。
这也叫做名称修饰(name mangling) - 解释器更改变量的名称,以便在类被扩展的时候不容易产生冲突。
class Test: def __init__(self): self.foo = 11 self._bar = 23 self.__baz = 23
a = Test()
print(a.__dict__)
打印结果:
{'foo': 11, '_bar': 23, '_Test__baz': 23}
如果你仔细观察,你会看到此对象上有一个名为_Test__baz的属性。 这就是Python解释器所做的名称修饰。 它这样做是为了防止变量在子类中被重写。
编写一个子类来继承Test类。
class Test: def __init__(self): self.foo = 11 self._bar = 23 self.__baz = 23 class ExtendedTest(Test): def __init__(self): super().__init__() self.foo = 'overridden' self._bar = 'overridden' self.__baz = 'overridden' t2 = ExtendedTest() print(t2.foo) 'overridden' print(t2._bar) 'overridden' print(t2.__baz) # 会报错
打印t2中的属性:
{'foo': 'overridden', '_bar': 'overridden', '_Test__baz': 23, '_ExtendedTest__baz': 'overridden'}
发现两个__baz属性通过类名区分开了。
_Test__baz
_ExtendedTest__baz
这就是双下划线的作用,防止覆盖。
双下划线名称修饰对程序员是完全透明的。也就是说,你无法通过类名.__baz来访问该变量,需要在类中定义其他的方法,来返回__baz的值。
名称修饰会影响在一个类的上下文中,以两个下划线字符("dunders")开头的所有名称。
Python解释器自动将名称__mangled扩展为_MangledGlobal__mangled,因为它以两个下划线字符开头。
这表明名称修饰不是专门与类属性关联的。它适用于在类上下文中使用的两个下划线字符开头的任何名称。
_MangledGlobal__mangled = 23 class MangledGlobal: def test(self): return __mangled MangledGlobal().test() 23
4、前面和后面都有二个下划线 【python特殊用途】
前后带有双下划线的变量或方法,是作为特殊用途使用的。
__init__,对象构造函数,或__call__ ,它使得一个对象可以被调用。
最好避免在自己的程序中使用以双下划线(“dunders”)开头和结尾的名称,以避免与将来Python语言的变化产生冲突。
也就是说,尽量不要在你的程序中使用前后双下划线,如果以后官方改了,你也得跟着改,没法很好的适配。
5、单下划线 【临时变量 + 存储上一次的值】
按照习惯,有时候单个独立下划线是用作一个名字,来表示某个变量是临时的或无关紧要的。
在下面的循环中,我们不需要访问正在运行的索引,我们可以使用“_”来表示它只是一个临时值。
for _ in range(32): ... print('Hello, World.')
同样,这个含义只是“依照约定”,并不会在Python解释器中触发特殊的行为。 单个下划线仅仅是一个有效的变量名称,会有这个用途而已。
你也可以在拆分(unpacking)表达式中将单个下划线用作“不关心的”变量,以忽略特定的值。
car = ('red', 'auto', 12, 3812.4) color, _, _, mileage = car color 'red'
mileage 3812.4
_ 12
'_' 还可以表示最近一个表达式的结果,好比Linux中的-表示上次访问的目录。
20 + 3 23 >>> _ 23 >>> print(_) 23
总结:

 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号