前面章節已經介紹了python中的多态和繼承,本節将介紹面向對象程式設計oop三大特征的另一個特征--封裝。
一、 概念
封裝是将對象的狀态資訊(也就是資料、屬性)隐藏在對象内部,将對象的屬性和實作細節隐藏起來,不允許外部程式直接通路對象内部資訊,而是通過類所提供的方法來實作對内部資訊的操作和通路,讓方法來控制對這些屬性進行安全的通路和操作。實際上封裝有兩個方面的含義:把該隐藏的隐藏起來,把該暴露的暴露出來。
封裝除了隐藏類的資料和實作細節外,可以達到如下目的:
1. 讓調用方隻能通過類定義的方法來通路類和對象内部的屬性和資料,進而可以在相關方法裡加入控制邏輯,對資料進行檢查和處理,確定屬性的通路符合設計者的預期;
2. 便于修改,所有對該資料的通路都通過方法進行,開發人員隻需要保證調用格式和傳回資料格式保持不變就可以相容原有的調用代碼,無需修改調用方代碼,提高代碼的可維護性。
二、 python封裝機制
在大部分面向對象開發的語言如c++和java語言中,封裝是通過私有成員和方法實作的,而python沒有顯示定義私有成員的方法,其封裝是利用了變量和方法命名的特殊處理來實作的。具體來說:
1. 如果要讓内部屬性不被外部通路,可以把屬性(含方法)的名稱前加上兩個下劃線,在python中,執行個體的變量名和方法名如果以兩個下劃線開頭(但不能是兩個下劃線結尾),就變成了一個私有變量(private),隻有内部可以通路,外部不能通路:
1) python的私有變量,直接在外部通過執行個體是無法通路的;
2) python私有變量的實作方式是,在python編譯時,對于類定義中所有以兩個下劃線打頭(但不能是兩個下劃線結尾)的名稱都進行轉換,在開頭加上一個下劃線和類名;
3) python這種幕後處理手法,使得開發人員能通過名字變換從類和對象外通路私有屬性和方法,但這種方式應該禁止,因為直接通路可能導緻程式不能遵循設計和開發人員對資料的控制,導緻意外的錯誤。
2. 在python中,變量名類似__xxx__的,也就是以雙下劃線開頭并且以雙下劃線結尾的變量和方法,是特殊變量,特殊變量是可以直接通路的,不是私有變量,是以,一般執行個體變量和類變量以及方法不能用__xxx__這樣的方式命名;
3. 在python中,除了雙下劃線開頭變量是私有變量外,還有一種變量名或方法名以一個下劃線開頭,這樣的執行個體變量和方法外部是可以通路的,但是,按照約定俗成的規定,當你看到這樣的變量時,請視為私有變量不要随意通路。python對這種變量,執行from module import * 不會導入,也就是說import如果不指定導入的方法名,導入時對子產品中以一個下劃線打頭的名稱的方法不會導入。
從上所述,python的封裝與正常的oop語言差異比較大,它沒有為私有屬性提供直接的支援,要讓方法或屬性成為私有的,隻需讓其名稱以兩個下劃線打頭即可。這種處理要求程式員知道在什麼情況下從外部修改屬性是安全的。是以python無法禁止别人通路對象的私有方法和屬性,但這種名稱修改方式發出了強烈的信号,讓他們不要這樣做。
本節介紹了python中類的封裝機制,下節将結合一個案例詳細說明。