除了普通的類方法,python 類還可以定義專用方法。專用方法是在特殊情況下或當使用特別語法時由 python 替你呼叫的,而不是在**中直接呼叫 (像普通的方法那樣)。
就像你在上一節所看到的,普通的方法對在類中封裝字典很有幫助。但是只有普通方法是不夠的,因為除了對字典呼叫方法之外,還有很多事情可以做的。例如,你可以通過一種沒有包括明確方法呼叫的語法來獲得和設定資料
項。這就是專用方法產生的原因:它們提供了一種方法,可以將非方法呼叫語法對映到方法呼叫上。
1. __getitem__ 專用方法
def __getitem__(self, key): return self.data[key]
>>> f = fileinfo.fileinfo("/music/_singles/kairo.***")
>>> f
>>> f.__getitem__("name") (1)
'/music/_singles/kairo.***'
>>> f["name"] (2)
'/music/_singles/kairo.***'
(1) __getitem__ 專用方法很簡單。像普通的方法 clear,keys 和 values 一樣,它只是重定向到字典,返回字典的值。但是怎麼呼叫它呢?哦,你可以直接呼叫 __getitem__,但是在實際中你其實不會那樣做:我在這裡執行它只是要告訴你它是如何工作的。正確地使用 __getitem__ 的方法是讓 python 來替你呼叫。
(2) 這個看上去就像你用來得到乙個字典值的語法,事實上它返回你期望的值。下面是隱藏起來的乙個環節:暗地裡,python 已經將這個語法轉化為 f.__getitem__("name") 的方法呼叫。這就是為什麼 __getitem__ 是乙個專用類方法的原因,不僅僅是你可以自已呼叫它,還可以通過使用正確的語法讓 python 來替你呼叫。
當然,python 有乙個與 __getitem__ 類似的 __setitem__ 專用方法,參見下面的例子。
2. __setitem__ 專用方法
def __setitem__(self, key, item): self.data[key] = item
>>> f
>>> f.__setitem__("genre", 31) (1)
>>> f
>>> f["genre"] = 32 (2)
>>> f
(1) 與 __getitem__ 方法一樣,__setitem__ 簡單地重定向到真正的字典 self.data ,讓它來進行工作。並且像 __getitem__ 一樣,通常你不會直接呼叫它,當你使用了正確的語法,python 會替你呼叫 __setitem__ 。
(2) 這個看上去像正常的字典語法,當然除了 f 實際上是乙個類,它盡可能地打扮成乙個字典,並且 __setitem__ 是打扮的乙個重點。這行**實際上暗地裡呼叫了 f.__setitem__("genre", 32)。__setitem__ 是乙個專用類方法,因為它可以讓 python 來替你呼叫,但是它仍然是乙個類方法。就像在 userdict 中定義 __setitem__ 方法一樣容易,我們可以在子類中重新定義它,對父類的方法進行覆蓋。這就允許我們定義出在某些方面像字典一樣動作的類,但是可以定義它自已的行為,超過和超出內建的字典。
這個概念是本章中我們正在學習的整個框架的基礎。每個檔案型別可以擁有乙個處理器類,這些類知道如何從乙個特殊的文型別得到元資料。只要知道了某些屬性 (像檔名和位置),處理器類就知道如何自動地得到其它的屬性。它的實現是通過覆蓋 __setitem__ 方法,檢查特別的關鍵字,然後當找到後加入額外的處理。
例如,***fileinfo 是 fileinfo 的子類。在設定了乙個 ***fileinfo 類的 name 時,並
不只是設定 name 關鍵字 (像父類 fileinfo 所做的),它還要在檔案自身內進行搜尋 *** 的標記然後填充一整套關鍵字。下面的例子將展示其工作方式。
3. 在 *** fil ein fo 中覆蓋 __setitem__
def __setitem__(self, key, item): (1)
if key == "name" and item: (2)
self.__parse(item) (3)
fileinfo.__setitem__(self, key, item) (4)
(1) 注意我們的 __setitem__ 方法嚴格按照與父類方法相同的形式進行定義。這一點很重要,因為 python 將替你執行方法,而它希望這個函式用確定個數的引數進行定義。(從技術上說,引數的名字沒有關係,只是個數。)
(2) 這裡就是整個 ***fileinfo 類的難點:如果給 name 關鍵字賦乙個值,我們還想做些額外的事情。
(3) 我們對 name 所做的額外處理封裝在了 __parse 方法中。這是定義在 ***fileinfo 中的另乙個類方法,則當我們呼叫它時,我們用 self 對其限定。僅是呼叫 __parse 將只會看成定義在類外的普通方法,呼叫 self.__parse 將會看成定義在類中的乙個類方法。這不是什麼新東西,你用同樣的方法來引用資料屬性。
(4) 在做完我們額外的處理之後,我們需要呼叫父類的方法。記住,在 python 中不會自動為你完成,需手工執行。注意,我們在呼叫直接父類,fileinfo,儘管它沒有 __setitem__ 方法。沒問題,因為 python 將會沿著父類樹走,直到它找到乙個擁有我們正在呼叫方法的類,所以這行**最終會找到並且呼叫定義在 userdict 中的 __setitem__。
4. 設定 *** fil ein fo 的 name
>>> import fileinfo
>>> ***file = fileinfo.***fileinfo() (1)
>>> ***file
>>> ***file["name"] = "/music/_singles/kairo.***" (2)
>>> ***file
>>> ***file["name"] = "/music/_singles/sidewinder.***" (3)
>>> ***file
(1) 首先,我們建立了乙個 ***fileinfo 的例項,沒有傳遞給它檔名。(我們可以不用它,因為 __init__ 方法的 filename 引數是可選的。) 因為 ***fileinfo 沒有它自已的 __init__ 方法,python 沿著父類樹走,發現了 fileinfo 的 __init__ 方法。這個 __init__ 方法手工呼叫了 userdict 的 __init__ 方法,然後設定 name 關鍵字為 filename,它為 none,因為我們還沒有傳入乙個檔名。所以,***file 最初看上去像是有乙個關鍵字的字典,name 的值為 none。
(2) 現在真正有趣的開始了。設定 ***file 的 name 關鍵字觸發了 ***fileinfo 上的 __setitem__ 方法 (而不是 userdict 的),這個方法注意到我們正在用乙個真實的值來設定 name 關鍵字,接著呼叫 self.__parse。儘管我們完全還沒有研究過 __parse 方法,從它的輸出你可以看出,它設定了其它幾個關鍵字:album、artist、genre、title、year 和 comment。
(3) 修改 name 關鍵字將再次經受同樣的處理過程:python 呼叫 __setitem__,__setitem__呼叫 self.__parse,self.__parse 設定其它所有的關鍵字。
Python類的專用方法
python 類可以定義專用方法,專用方法是在特殊情況下或當使用特別語法時由 python 替你呼叫的,而不是在 中直接呼叫 象普通的方法那樣 1 init 類似於建構函式 usr local bin python class study def init self,name none self.n...
Python類的專用方法
python 類可以定義專用方法,專用方法是在特殊情況下或當使用特別語法時由 python 替你呼叫的,而不是在 中直接呼叫 象普通的方法那樣 1 init 類似於建構函式 usr local bin python class study def init self,name none self.n...
Python類的專用方法
2009 05 13 15 43 47 標籤 python 休閒職場 原始出處 作者資訊和本宣告。否則將追究法律責任。python 類可以定義專用方法,專用方法是在特殊情況下或當使用特別語法時由 python 替你呼叫的,而不是在 中直接呼叫 象普通的方法那樣 1 init 類似於建構函式 usr ...