一、关于成员可见性
默认情况下,Class内部创建的属性和方法,外部代码是可以通过实例直接操作的;但有时候为了保证封装性,我们不希望这些内部属性被外部直接访问。这就需要设置成员可见性。
设置方法:在属性和方法名前面添加两个下划线__;
作用:确保了外部代码不能随意修改对象内部的状态,可以在外部访问时做一些容错性判断,代码更加健壮;
外部访问:如果设置私有后,外部代码仍需要访问这些私有属性,可以在当前类中添加公开的get和set方法
二、实现类的私有属性和私有方法
class Student():
def __init__(self,name,age=18):
self.name= name
self.age = age
self.__restScore() #内部访问私有方法
self.__score = 0 #内部访问私有属性
#私有方法:重置分数
def __restScore(self):
self.__score = 50
#公开方法:获取分数
def get__score(self):
print(self.name +"的分数:"+ str(self.__score))
#公开方法:设置分数,增加容错处理分数不能为负数
def set__score(self,score):
if score < 0:
self.__score = 0
return
self.__score = score
测试成员可见性的代码如下:
stu = Student("小冬")
#stu.resetScore() #报错,不能直接访问私有方法
#print(stu.__score) #报错,不能直接方法私有属性
stu.get__score() #通过公开方法访问和设置分数
stu.set__score(-1)
stu.get__score() #0
stu.set__score(66)
stu.get__score() #66
三、理解私有成员的原理
我们不能动态设置私有变量,因为其内部的私有属性已经被Python解释器更改为_Student__score,使用dict可以打印对象的内部属性,我们可以借助它测试,代码如下:
print(stu.__dict__) #打印stu内部属性构成
stu.__score = 100 #设置__score变量
print(stu.__dict__) #打印stu内部属性构成
'''
{'name': '小冬', 'age': 18, '_Student__score': 66}
{'name': '小冬', 'age': 18, '_Student__score': 66, '__score': 100}
'''
总结:外部代码的这个操作实际上增加了一个__score变量,并没有影响到真正的私有属性
四、最后总结
1.Python中特殊变量
Python中自带的变量名类似”__xxx__”的,也就是以双下划线开头,并且以双下划线结尾的变量,是特殊变量。特殊变量是可以直接访问的,不是private变量,所以我们命名时不推荐使用用__name__、__score__这样的形式。
2.双下划线的实例变量并不是一定不能从外部访问。
如代码中不能直接访问__score是因为Python解释器对外把__score变量改成了_Student__score,所以,仍然可以通过_Student__score来访问__name变量,但是强烈建议你不要这么干,因为不同版本的Python解释器还可能会把__score改成不同的变量名。
3.总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。