隱藏物件的某些屬性和實現的細節,僅僅只對外提供公共訪問的方式。將函式和屬性裝到了乙個非全域性的命名空間。
封裝的好處
(1)將變化隔離
(2)便於使用
(3)提高復用性
(4)提高安全性
(1)將不需要對外提供的內容全部都隱藏起來
(2)吧屬性都隱藏,提供公共方法對其訪問
私有變數:不能在類的外面去引用它。
它依然存在於__dict__中,我們仍然可以呼叫到。只是python對其的名字進行了修改: _類名__名字。但是在類的外部呼叫 :需要「_類名__名字」去使用,在類的內部可以正常的使用名字
在python中定義乙個私有的名字 :使用兩條下劃線開頭的方式來定義變數名稱 __n = 『aaa』
print(student._student__id) #不報錯class student:
__id = 0 #變成了私有的靜態變數類的資料屬性就應該是
# 共享的,但是語法上是可以把類的資料屬性設定成私有的如__n,會變形為_a__n
def __init__(self, name, age):
self.name = name #變形為self._student__name ,私有屬性
self.age = age #變形為self._student__age ,私有屬性
def func(self):
print(student.__id) #在類的內部使用正常
s = student('hh', 18)
s.func()
print(student.__id) # 在類的外部直接使用 報錯
由此,私有變數只能在類的內部訪問的到,外部不能訪問,但是,由於它是乙個變形的方式。其實可以通過變形以後的方式進行訪問,但嚴格意義上來講,我們不能通過它來訪問,這時只有我們程式設計師知道就可以了
這種自動變形的特點:
1.類中定義的__x只能在內部使用,如self.__x,引用的就是變形的結果。
2.這種變形其實正是針對外部的變形,在外部是無法通過__x這個名字訪問到的。
3.在子類定義的__x不會覆蓋在父類定義的__x,因為子類中變形成了:_子類名__x,而父類中變形成了:_父類名__x,即雙下滑線開頭的屬性在繼承給子類時,子類是無法覆蓋的。
變形需要注意的問題是:
1.這種機制也並沒有真正意義上限制我們從外部直接訪問屬性,知道了類名和屬性名就可以拼出名字:_類名__屬性,然後就可以訪問了,如a._a__n
2.變形的過程只在類的內部生效,在定義後的賦值操作,不會變形
私有方法的定義和私有變數一樣,只需要在前面加上雙下劃線,就是標誌著私有方法
在繼承中,父類如果不想讓子類覆蓋自己的方法,可以將方法定義為私有的class student:
def func(self):
print("我是乙個好學生") # 在類的內部使用正常
def __adca(self):
print("我喜歡喝adca")
s = student()
s.func() #普通方法呼叫
s._student__adca() #私有方法呼叫
s.__adca #這樣呼叫,直接報錯
總之,在類中,靜態屬性,方法,物件屬性都可以變成私有的,只需要在這些名字之前加上__#正常情況,方法都是普通方法
class dad:
def dear(self):
print('from dad')
def father(self):
self.dear()
class son(dad):
def dear(self):
print('from son')
s = son()
s.father()
#當某乙個方法是私有的時候,子類就不能繼承父類的私有方法了
class dad:
def dear(self):
print('from dad')
def __father(self):
self.dear()
class son(dad):
def dear(self):
print('from son')
s = son()
s.father()
私有的名字,在類內使用的時候,就是會變形成_該類名__方法名。下面這個例子:
以此為例 :沒有雙下換線會先找e中的func,但是有了雙下劃線,會在呼叫這個名字的類d中直接找_d__func
封裝在於明確區分內外,使得類實現者可以修改封裝內的東西而不影響外部呼叫者的**;而外部使用用者只知道乙個介面(函式),只要介面(函式)名、引數不變,使用者的**永遠無需改變。這就提供乙個良好的合作基礎——或者說,只要介面這個基礎約定不變,則**改變不足為慮。class d:
def __init__(self):
self.__func()
def __func(self):
print('in d')
class e(d):
def __func(self):
print('in e')
e = e() #結果:in d
#類的設計者,輕鬆的擴充套件了功能,而類的使用者完全不需要改變自己的**
class room:
def __init__(self,name,owner,width,length,high):
self.name=name
self.owner=owner
self.__width=width
self.__length=length
self.__high=high
def tell_area(self): #對外提供的介面,隱藏內部實現,此時我們想求的是體積,內部邏輯變了,
#只需求修該下列一行就可以很簡答的實現,而且外部呼叫感知不到,仍然使用該方法,但是功能已經變了
return self.__width * self.__length * self.__high #對於仍然在使用tell_area介面的人來說,根本無需改動自己的**,就可以用上新功能
python物件導向三大特性之封裝
封裝 類裡面不光有屬性還有方法。這種將屬性通過方法直接在類內部操作的形式就叫做封裝。把很多資料封裝到 個物件中,把固定功能的 封裝到 個 塊,函式,物件,打包成模組.這都屬於封裝的思想.封裝操作可以對受保護的成員進行功能開放的控制,達到保護資料不被非法訪問的目的。當然,方法也可以私有封裝,但是一般都...
python物件導向三大特性之封裝
封裝是物件導向三大特性最核心的乙個特性 封裝 整合 1 如何隱藏 在屬性名前加 字首,就會實現乙個對外隱藏屬性效果 該隱藏需要注意的問題 i 在類外部無法直接訪問雙下滑線開頭的屬性,但知道了類名和屬性名就可以拼出名字 類名 屬性,然後就可以訪問了,如foo.a n,所以說這種操作並沒有嚴格意義上地限...
Python物件導向三大特性之封裝
面向函式的程式設計和物件導向程式設計對比 通過函式和物件的方法實現同樣的功能,看起來是面向函式的程式設計比較簡單 假如是連線資料庫的增,刪,改,查操作使用物件導向的方法 更加簡單 vim day7 3.py usr bin python coding utf 8 def fetch 連線資料庫,ho...