在Python中单下划线和双下划线有着不同的含义和命名约定,影响着程序执行的结果。下面介绍五种不同的下划线:
以单下划线开始的成员变量相当于私有变量,也叫做保护变量,也就是只有类实例和子类实例能访问到这些变量,需通过类提供的接口进行访问。不能用’from module import *'导入。其实,Python并没有真正的私有化支持,用下划线得到的是伪私有,也就是说如果你强行要用也是可以的,但不符合python的规范。
class Test:
def __init__(self):
self.foo = 11
self._bar = 23
# 测试代码:
>>> t = Test()
>>> t.foo
11
>>> t._bar
23
但是,前导下划线的确会影响从模块中导入名称的方式。
# my_module.py文件
def external_func():
print('模块导入成功')
def _internal_func():
print('模块导入成功')
# 测试代码:
>>> from my_module import *
>>> external_func()
模块导入成功
>>> _internal_func()
NameError: "name '_internal_func' is not defined"
当变量最合适的名称已经被一个关键字所占用时(像class或def这样的名称不能用作Python中的变量名称),可以附加一个下划线来解决命名冲突。
>>> def make_object(name, class):
SyntaxError: "invalid syntax"
>>> def make_object(name, class_):
pass
类中的私有变量/方法名,会导致Python解释器重写属性名称,以避免子类中的命名冲突。只有类对象自己能访问,连子类对象也不能访问到这个数据。
class Person:
def __init__(self):
self.name = 'van'
self.age = 100
self.__height = 200
class Gao(Person):# 继承Person
def __init__(self):
super().__init__()# 继承父类_init__中的属性
self.name = 'gao'
p = Person()# 实例化
g = Gao()
print(dir(p))
print(dir(g))
print(p.name)
print(p.age)
print(g.name)# 重写变量name
print(g.age)# 继承age
print(p._Person__height)# 访问私有变量的方法:_类名__变量名
输出结果如下:
['_Person__height', '__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__', 'age', 'name']
['_Person__height', '__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__', 'age', 'name']
van
100
gao
100
200
子类Gao
访问父类Person
的私有变量
# 错误方法
print(g.__height)
AttributeError: 'Gao' object has no attribute '__height'
# 正确方法
print(p._Person__height)
print(g._Person__height)
python里特殊方法专用的标识,如__init__
代表类的构造函数,或__call__
它使得一个对象可以被调用。。类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如一个模块的__author__,__name__就是特殊变量,模块定义的文档注释(就是模块开头的字符串)也可以用特殊变量__doc__访问。
class model():
def __init__(self):
# 初始化变量
self.var1 = 1
self.var2 = one
单个独立下划线是用作一个名字,来表示某个变量是临时的或无关紧要的。换句话说充当占位符。
for _ in range(3):
print('输出3次')
# 输出结果:
输出5次
输出5次
输出5次
# 占位符
num = (1,2,3)
one,_,_ = num
print(one)
# 输出结果:
1
除了用作临时变量之外,“_”是大多数Python REPL中的一个特殊变量,它表示由解释器评估的最近一个表达式的结果。
>>> 1+1
2
>>> _
2
>>>
参考链接: link.