面向對象——封裝
阿新 • • 發佈:2018-07-23
put obj 訪問 下滑 外部 認證 如果 開頭 整型
封裝
將具體、復雜的細節封裝在一起。
1. 如何將屬性隱藏
如果想讓屬性或方法隱藏,在其前加 ‘__’ 雙下劃線,python就將其視為私有。
註意:
(1). 私有變量是在定義時生成的。
(2). python沒有實現絕對的私有,而是在定義時將私有屬性解析 ‘_類名__屬性’,(單下劃線類名雙下劃線屬性)
#其實這僅僅這是一種變形操作 #類中所有雙下劃線開頭的名稱如__x都會自動變形成:_類名__x的形式: class A: __x = 1 #定義時被解釋為 _A__x def __init__(self, name): self.__name = name #定義時被解釋為 self._A__name def __foo(self): #定義時被解釋為 _A__foo print(‘run foo‘) def bar(self): self.__foo() #只有在類內部才可以通過__foo的形式訪問到. # 外部無法通過‘類名.屬性’的方式訪問 # print(A.__x) AttributeError: type object ‘A‘ has no attribute ‘__x‘ a = A(‘yk‘) print(a.__dict__) # {‘_A__name‘: ‘yk‘}print(_A__name) # yk 可以通過_類名__x的形式訪問
特點:
1.類中定義的__x只能在內部使用,如self.__x,引用的就是變形的結果。
2.這種變形其實正是針對外部的變形,在外部是無法通過__x這個名字訪問到的。
3.在子類定義的__x不會覆蓋在父類定義的__x,因為子類中變形成了:_子類名__x,而父類中變形成了:_父類名__x,即雙下滑線開頭的屬性在繼承給子類時,子類是無法覆蓋的。
問題:
1、這種機制也並沒有真正意義上限制我們從外部直接訪問屬性,知道了類名和屬性名就可以拼出名字:_類名__屬性,然後就可以訪問了,如a._A__N。
2、變形的過程只在類的定義是發生一次,在定義後的賦值操作,不會變形
3、在繼承中,父類如果不想讓子類覆蓋自己的方法,可以將方法定義為私有的
#正常情況 class A: def fa(self): print(‘from A‘) def test(self): self.fa() class B(A): def fa(self): print(‘from B‘) b=B() b.test() # from B #把fa定義成私有的,即__fa class A: def __fa(self): #在定義時就變形為_A__fa print(‘from A‘) def test(self): self.__fa() #只會與自己所在的類為準,即調用self._A__fa class B(A): def __fa(self): print(‘from B‘) b=B() b.test() # from A
2. 封裝不是單純意義的隱藏
# 1:封裝數據。將數據隱藏起來這不是目的。 # 隱藏起來然後對外提供操作該數據的接口,然後我們可以在接口附加上對該數據操作的限制, # 以此完成對數據屬性操作的嚴格控制。 class People: def __init__(self,name,age): self.__name = name self.__age = age # 訪問接口 def tell_info(self): print(‘姓名:%s,年齡:%s‘ % (self.__name, self.__age)) # 修改接口 def set_info(self, name, age): # 添加自己的控制邏輯 if not isinstance(name, str): raise TypeError(‘姓名必須是字符串類型‘) if not isinstance(age, int): raise TypeError(‘年齡必須是整型‘) self.__name = name self.__age = age p = People(‘yk‘,18) p.tell_info() # yk,年齡:18 p.set_info(‘小明‘,15) p.tell_info() # 小明,年齡:15 p.set_info(‘小花‘,‘14‘) # 報錯 TypeError: 年齡必須是整型
# 2:封裝方法,隔離復雜度 #取款是功能,而這個功能有很多功能組成:插卡、密碼認證、輸入金額、打印賬單、取錢 #對使用者來說,只需要知道取款這個功能即可,其余功能我們都可以隱藏起來,很明顯這麽做 #隔離了復雜度,同時也提升了安全性. class ATM: def __card(self): print(‘插卡‘) def __auth(self): print(‘用戶認證‘) def __input(self): print(‘輸入取款金額‘) def __print_bill(self): print(‘打印賬單‘) def __take_money(self): print(‘取款‘) def withdraw(self): self.__card() self.__auth() self.__input() self.__print_bill() self.__take_money() a=ATM() a.withdraw()
面向對象——封裝