Python 專用類方法

2021-06-15 07:45:10 字數 3816 閱讀 2285

除了普通的類方法,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 ...