属性的访问权限
- 公有。属性名前面没有其他符号,可以在 类内部、类外部 使用
- 私有。属性名前面 两个下划线
_ _,只能在 类内部 使用 - 类内部、子类可继承。属性名前面 一个下划线
_,是规范,程序员之间的 约定:不要在类外部使用。(但其实在外部可以使用)
提出问题
在手机中,像下图红框处的信息,都是出厂时设置好的,并且一般情况下不可更改的,只能访问这些信息。
分析
在面向对象编程中,不允许外部修改这些属性,此时就要将这些属性设置为 私有
新问题
但是,设置为私有后,在外部不能访问这些属性,为了达到访问的目的,只能通过 方法 去访问这些信息
定义私有属性
属性的名称前加上 两个下划线_ _,那么只有内部可以访问,外部和子类不能直接访问
代码如下:
#coding=utf=8
class Phone:
'''手机类'''
def __init__(self,name,imei):
print("调用__init__()",",name=",name)
self.__name=name
self.__imei=imei
def call(self,number):
print("用 "+self.__name+" 打电话给 "+number)
iphone=Phone("iphoneX","12345678")
#下面调用方式会报错
print(iphone.__name)
print(iphone.__imei)
报错信息如下:
AttributeError: 'Phone' object has no attribute '__name'
不能直接访问私有变量
私有属性的本质 -_-
继续编码:
print(iphone.__dict__)
结果如下:
{'_Phone__name': 'iphoneXS', '_Phone__imei': '123ABCD'}
可知属性__name和__imei被python改名了,改成:_Phone__name
双下划线作用之二:
避免和父类的属性同名
在python中,双下滑线“__的属性”,在有的python解释器中被改名为“_类名__属性”了,可以通过下面代码直接访问:
#不要这么操作,不符合规范
print(iphone._Phone__name)
增加 get() 方法访问私有属性
为了能够访问私有属性,要增加 get方法,方法名字一般为: get_属性名(),如下:
#coding=utf=8
class Phone:
'''手机类'''
def __init__(self,name,imei):
print("调用__init__()",",name=",name)
self.__name=name
self.__imei=imei
def call(self,number):
print("用 "+self.__name+" 打电话给 "+number)
#增加get_name方法
def get_name(self):
return self.__name
#增加get_imei方法
def get_imei(self):
return self.__imei
#创建实例
iphone=Phone("iphoneX","12345678")
#通过方法访问属性
print(iphone.get_name())
print(iphone.get_imei())
增加 set() 方法修改私有属性
将属性定义为私有,通过 set 方法修改属性,好处是可以做 校验
总结
面向对象编程的特征之一是封装,将类中属性设置为私有,不能直接设置、访问属性,而是通过set、get方法。
