溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么實(shí)現(xiàn)Python封裝機(jī)制

發(fā)布時間:2020-08-25 16:32:35 來源:億速云 閱讀:133 作者:Leah 欄目:編程語言

怎么實(shí)現(xiàn)Python封裝機(jī)制?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

封裝(Encapsulation)是面向?qū)ο蟮娜筇卣髦唬硗鈨蓚€是繼承和多態(tài)),它指的是將對象的狀態(tài)信息隱藏在對象內(nèi)部,不允許外部程序直接訪問對象內(nèi)部信息,而是通過該類所提供的方法來實(shí)現(xiàn)對內(nèi)部信息的操作和訪問。

封裝是面向?qū)ο缶幊陶Z言對客觀世界的模擬,在客觀世界里,對象的狀態(tài)信息都被隱藏在對象內(nèi)部,外界無法直接操作和修改。對一個類或?qū)ο髮?shí)現(xiàn)良好的封裝,可以達(dá)到以下目的:

隱藏類的實(shí)現(xiàn)細(xì)節(jié)。

讓使用者只能通過事先預(yù)定的方法來訪問數(shù)據(jù),從而可以在該方法里加入控制邏輯,限制對屬性的不合理訪問。

可進(jìn)行數(shù)據(jù)檢查,從而有利于保證對象信息的完整性。

便于修改,提高代碼的可維護(hù)性。

為了實(shí)現(xiàn)良好的封裝,需要從以下兩個方面來考慮:

將對象的屬性和實(shí)現(xiàn)細(xì)節(jié)隱藏起來,不允許外部直接訪問。

把方法暴露出來,讓方法來控制對這些屬性進(jìn)行安全的訪問和操作。

因此,實(shí)際上封裝有兩個方面的含義:把該隱藏的隱藏起來,把該暴露的暴露出來。

Python 并沒有提供類似于其他語言的 private 等修飾符,因此 Python 并不能真正支持隱藏。為了隱藏類中的成員,Python 玩了一個小技巧:只要將 Python 類的成員命名為以雙下畫線開頭的,Python 就會把它們隱藏起來。

例如,如下程序示范了 Python 的封裝機(jī)制:

class User :
    def __hide(self):
        print('示范隱藏的hide方法')
    def getname(self):
        return self.__name
    def setname(self, name):
        if len(name) < 3 or len(name) > 8:
            raise ValueError('用戶名長度必須在3~8之間')
        self.__name = name
    name = property(getname, setname)
    def setage(self, age):
        if age < 18 or age > 70:
            raise ValueError('用戶名年齡必須在18在70之間')
        self.__age = age
    def getage(self):
        return self.__age
    age = property(getage, setage)
# 創(chuàng)建User對象
u = User()
# 對name屬性賦值,實(shí)際上調(diào)用setname()方法
u.name = 'fk' # 引發(fā) ValueError: 用戶名長度必須在3~8之間

上面程序?qū)?User 的兩個實(shí)例變量分別命名為 __name 和 __age,這兩個實(shí)例變量就會被隱藏起來,這樣程序就無法直接訪問 __name、__age 變量,只能通過 setname()、getname()、setage()、getage() 這些訪問器方法進(jìn)行訪問,而 setname()、setage() 會對用戶設(shè)置的 name、age 進(jìn)行控制,只有符合條件的 name、age 才允許設(shè)置。

上面程序用到了 raise 關(guān)鍵字來拋出異常,關(guān)于 raise 關(guān)鍵字和異常的相關(guān)信息,后續(xù)章節(jié)會詳細(xì)介紹。

上面程序嘗試將 User 對象的 name 設(shè)為 fk,這個字符串的長度為“2”不符合實(shí)際要求,因此運(yùn)行程序最后一行包含如下錯誤:

ValueError:用戶名長度必須在3-8之間

將最后一行代碼注釋掉,并在程序尾部添加如下代碼:

u.name = 'fkit'
u.age = 25
print(u.name) # fkit
print(u.age) # 25

此時程序?qū)?name、age 所賦的值都符合要求,因此上面兩行賦值語句完全可以正常運(yùn)行。運(yùn)行上面代碼,可以看到如下輸出結(jié)果:

fkit
25

從該程序可以看出封裝的好處,程序可以將 User 對象的實(shí)現(xiàn)細(xì)節(jié)隱藏起來,程序只能通過暴露出來的 setname()、setage() 方法來改變 User 對象的狀態(tài),而這兩個方法可以添加自己的邏輯控制,這種控制對 User 的修改始終是安全的。

上面程序還定義了一個 hide() 方法,這個方法默認(rèn)是隱藏的。如果程序嘗試執(zhí)行如下代碼:

# 嘗試調(diào)用隱藏的__hide()方法
u.__hide()

將會提示如下錯誤:

AttributeError:'User' object has no attribute 'hide'

最后需要說明的是,Python 其實(shí)沒有真正的隱藏機(jī)制,雙下畫線只是 Python 的一個小技巧,Python 會“偷偷”地改變以雙下畫線開頭的方法名,會在這些方法名前添加單下畫線和類名。因此上面的 __hide() 方法其實(shí)可以按如下方式調(diào)用(通常并不推薦這么干):

# 調(diào)用隱藏的__hide()方法
u._User__hide()

運(yùn)行上面代碼,可以看到如下輸出結(jié)果:

示范隱藏的hide 方法

通過上面調(diào)用可以看出,Python 并沒有實(shí)現(xiàn)真正的隱藏。

類似的是,程序也可通過為隱藏的實(shí)例變量添加下畫線和類名的方式來訪問或修改對象的實(shí)例變量。例如如下代碼:

# 對隱藏的__name屬性賦值
u._User__name = 'fk'
# 訪問User對象的name屬性(實(shí)際上訪問__name實(shí)例變量)
print(u.name)

上面粗體字代碼實(shí)際上就是對 User 對象的 name 實(shí)例變量進(jìn)行賦值,通過這種方式可“繞開”setname() 方法的檢查邏輯,直接對 User 對象的 name 屬性賦值。運(yùn)行這兩行代碼,可以看到如下輸出結(jié)果:

fk

總結(jié)

Python 并沒有提供真正的隱藏機(jī)制,所以 Python 類定義的所有成員默認(rèn)都是公開的;如果程序希望將 Python 類中的某些成員隱藏起來,那么只要讓該成員的名字以雙下畫線開頭即可。

即使通過這種機(jī)制實(shí)現(xiàn)了隱藏,其實(shí)也依然可以繞過去。


看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI