python之封裝


 

一、什么是封裝

在程序設計中,封裝(Encapsulation)是對具體對象的一種抽象,即將某些部分隱藏起來,在程序外部看不到,其含義是其他程序無法調用。

要了解封裝,離不開“私有化”,就是將類或者是函數中的某些屬性限制在某個區域之內,外部無法調用。

二、為什么要封裝

封裝數據的主要原因是:保護隱私(把不想別人知道的東西封裝起來)

封裝方法的主要原因是:隔離復雜度(比如:電視機,我們看見的就是一個黑匣子,其實里面有很多電器元件,對於用戶來說,我們不需要清楚里面都有些元件,電視機把那些電器元件封裝在黑匣子里,提供給用戶的只是幾個按鈕接口,通過按鈕就能實現對電視機的操作。)

提示:在編程語言里,對外提供的接口(接口可理解為了一個入口),就是函數,稱為接口函數,這與接口的概念還不一樣,接口代表一組接口函數的集合體。

三、封裝分為兩個層面

封裝其實分為兩個層面,但無論哪種層面的封裝,都要對外界提供好訪問你內部隱藏內容的接口(接口可以理解為入口,有了這個入口,使用者無需且不能夠直接訪問到內部隱藏的細節,只能走接口,並且我們可以在接口的實現上附加更多的處理邏輯,從而嚴格控制使用者的訪問)

第一個層面的封裝(什么都不用做):創建類和對象會分別創建二者的名稱空間,我們只能用類名.或者obj.的方式去訪問里面的名字,這本身就是一種封裝。

print(m1.brand) #實例化對象(m1.) print(motor_vehicle.tag) #類名(motor_vehicle.) -------------輸出結果-------------- 春風 fuel oil

注意:對於這一層面的封裝(隱藏),類名.和實例名.就是訪問隱藏屬性的接口

第二個層面的封裝:類中把某些屬性和方法隱藏起來(或者說定義成私有的),只在類的內部使用、外部無法訪問,或者留下少量接口(函數)供外部訪問。

Python中私有化的方法也比較簡單,即在准備私有化的屬性(包括方法、數據)名字前面加兩個下划線即可。

類中所有雙下划線開頭的名稱如_x都會自動變形成:類名__x的形式:

class A: __N=0 #類的數據屬性就應該是共享的,但是語法上是可以把類的數據屬性設置成私有的如__N,會變形為_A__N def __init__(self): self.__X=10 #變形為self._A__X def __foo(self): #變形為_A__foo print('from A') def bar(self): self.__foo() #只有在類內部才可以通過__foo的形式訪問到. 

 

這種自動變形的特點:

1、類中定義的__x只能在內部使用,如self.__x,引用的就是變形的結果。

2、這種變形其實正是針對外部的變形,在外部是無法通過__x這個名字訪問到的。

3、在子類定義的_x不會覆蓋在父類定義的__x,因為子類中變形成了:子類名_x,而父類中變形成了:父類名__x,即雙下滑線開頭的屬性在繼承給子類時,子類是無法覆蓋的。

注意:對於這一層面的封裝(隱藏),我們需要在類中定義一個函數(接口函數)在它內部訪問被隱藏的屬性,然后外部就可以使用了

這種變形需要注意的問題是:

1、這種機制也並沒有真正意義上限制我們從外部直接訪問屬性,知道了類名和屬性名就可以拼出名字:類名_屬性,然后就可以訪問了,如a._A__N

a = A() print(a._A__N) print(a._A__X) print(A._A__N) --------輸出結果-------- 0 10 0

 

2、變形的過程只在類的定義是發生一次,在定義后的賦值操作,不會變形

a = A() #實例化對象a print(a.__dict__) #打印變形的內容 a.__Y = 20 #新增Y的值,此時加__不會變形 print(a.__dict__) #打印變形的內容 ---------輸出結果---------- {'_A__X': 10} {'_A__X': 10, '__Y': 20} #發現后面的Y並沒有變形

 

 

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被定義成私有的情況:

class A: #把fa定義成私有的,即__fa def __fa(self): #在定義時就變形為_A__fa print("from A") def test(self): self.__fa() #只會與自己所在的類為准,即調用_A__fa class B(A): def __fa(self): #b調用的是test,跟這個沒關系 print("from B") b = B() b.test() -------輸出結果--------- from A

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM