萌新学 Python 之面向对象的下划线控制权限访问
python 中访问的权限控制通过下划线 _ 来控制,类似于 java 中的 public 等
下划线在 python 中,不同的位置有不同的含义
1.单个下划线:主要作为临时变量或无意义的变量,当作占位符使用,可以忽略特定的值
# 临时变量用下划线取代
lst = [_ for _ in range(1, 11)]
print(lst) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2.下划线出现在变量的后面,比如 xx_ ,避免和关键字或者 python 自定义的内置函数冲突
def max_(*args): # 定义函数 max_ 避免冲突
print(max(args)) # max 内置函数
# 通过函数调用输出结果
max_(1, 2) # 2
3.面向对象中,通过下划线 _ 来控制权限访问
(1)没有下划线的变量(属性),这些属性表示公有的
(2)属性或方法前面添加单下划线,这些属性和方法表示受保护的,比如 _属性、_方法
(3)属性或方法前面添加双下划线,这些属性和方法表示私有的,比如 __属性、__方法
(4)属性或方法前面和后面添加双下划线,这些属性和方法通常具有特殊的用法,是 python 内置的属性和方法,比如 __init__、__dict__
在 python 中,权限只是一种约束,不强制阻止访问
不能使用 对象.__ 访问私有方法和私有属性,需要通过 _类名__私有属性和方法去访问
举例:
# 父类
class Father:
def __init__(self, name, _age, __addr):
self.name = name # 公有的属性
self._age = _age # 受保护的属性
self.__addr = __addr # 私有的属性
# 公有的方法
def introduce(self):
print(f'我是{self.name}')
# 受保护的方法
def _age_show(self):
print(f'{self._age}岁')
# 私有的方法
def __addr_show(self):
print(f'住在{self.__addr}')
# 实例化对象
f = Father('张三', 18, '北京')
# 访问公有的方法和属性
f.introduce() # 我是张三
print(f.name) # 张三
# 访问受保护的方法和属性
f._age_show() # 18岁
print(f._age) # 18
# 不能使用 对象.__ 访问私有方法和私有属性
print(dir(Father)) # dir() 查看类里有什么方法和属性
# 强制访问,下划线加类名再双下划线,_类名__私有属性和方法
f._Father__addr_show() # 住在北京
print(f._Father__addr) # 北京
# 子类,继承父类
class Son(Father):
def __init__(self, name, _age, __addr):
super().__init__(name, _age, __addr)
def father(self):
self.introduce() # 继承父类,访问公有方法
self._age_show() # 继承父类,访问受保护的方法
self._Father__addr_show() # 继承父类,访问私有的的方法,下划线加类名再双下划线,_类名__私有属性和方法
s = Son('张四', 1, '上海')
s.father() # 我是张四 1岁 住在上海
# 通过继承访问父类属性
print(s._Father__addr) # 上海