python的三大特性之封裝

2021-08-31 13:34:30 字數 3204 閱讀 8972

隱藏物件的某些屬性和實現的細節,僅僅只對外提供公共訪問的方式。將函式和屬性裝到了乙個非全域性的命名空間。

封裝的好處

(1)將變化隔離

(2)便於使用

(3)提高復用性

(4)提高安全性

(1)將不需要對外提供的內容全部都隱藏起來

(2)吧屬性都隱藏,提供公共方法對其訪問

私有變數:不能在類的外面去引用它。

它依然存在於__dict__中,我們仍然可以呼叫到。只是python對其的名字進行了修改: _類名__名字。但是在類的外部呼叫 :需要「_類名__名字」去使用,在類的內部可以正常的使用名字

在python中定義乙個私有的名字 :使用兩條下劃線開頭的方式來定義變數名稱 __n = 『aaa』

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) # 在類的外部直接使用 報錯

print(student._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...