一、關於成員可見性
默認情況下,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本身沒有任何機制阻止你幹壞事,一切全靠自覺。