python面向对象-实例属性的访问权限

属性的访问权限

  • 公有。属性名前面没有其他符号,可以在 类内部、类外部 使用
  • 私有。属性名前面 两个下划线 _ _,只能在 类内部 使用
  • 类内部、子类可继承。属性名前面 一个下划线 _,是规范,程序员之间的 约定:不要在类外部使用。(但其实在外部可以使用)

提出问题

在手机中,像下图红框处的信息,都是出厂时设置好的,并且一般情况下不可更改的,只能访问这些信息。

分析

在面向对象编程中,不允许外部修改这些属性,此时就要将这些属性设置为 私有

新问题

但是,设置为私有后,在外部不能访问这些属性,为了达到访问的目的,只能通过 方法 去访问这些信息

定义私有属性

属性的名称前加上 两个下划线_ _,那么只有内部可以访问,外部和子类不能直接访问
代码如下:

#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 方法修改属性,好处是可以做 校验

详见:python面向对象-实例属性的访问权限(例子)

总结

面向对象编程的特征之一是封装,将类中属性设置为私有,不能直接设置、访问属性,而是通过set、get方法。


原文出处:/show_1EF2CdsI4NWF.html