當前位置:
首頁 > 最新 > 符合 Python 風格的對象

符合 Python 風格的對象


符合 Python 風格的對象

在 Python 中,自定義的類也可以表現得像內置類型一樣自然,這都得益於鴨子類型:我們只需按照預定行為實現對象所需的方法即可。這篇文章主要介紹自定義類的一些特殊方法,來讓類的行為跟真正的 Python 對象一樣。


類的特殊方法是為了被解釋器調用,目的是可以將一些內置的方法用在對象上。比如特殊方法 是為了 函數的調用,我們在使用的時候就可以直接使用 這種寫法,而不是 ,如果 a 是自定義對象,Python 就會自己去調用我們自定義的 方法。

Python 中與運算符無關的特殊方法:

與運算符有關的特殊方法:

下面介紹幾個常用的特殊方法。


Python 提供了兩種獲取對象的字元串表示形式: 和 。

Python 有一個內置 函數,將一個對象用字元串形式表示出來,通過調用 這個特殊方法來實現的。同樣, 是通過調用 實現的。

在類中,我們需要實現 或 方法來實現將對象用字元串表示。需要注意的是, 所返回的字元串應該準確無歧義。

而 和 的區別在於,後者是在 函數被使用,或在用 print 函數列印對象的時候才被調用,並且它返回的字元串對終端用戶更友好;而一個對象沒有 函數, Python 又需要調用它的時候,解釋器會用 函數作為代替。

Python 內置的 方法和 方法將各個類型的格式化方法委託給相應的 方法。

如果類中沒有定義該方法,在對對象使用 方法時,從 object 繼承的方法會返回 。然而在這種情況下,有一種弊端就是如果我們傳入格式說明符, 方法會報錯。

我們希望得到的結果是對象的每個屬性都以我們傳入的形式表示出來。舉個例子:


為了實現類的散列化,我們需要實現 方法。根據散列化的定義,我們需要保證對象唯一不變,且需要返回對象屬性的散列值,所以另外需要實現 方法。

為了保證唯一不變,我們需要將對象屬性設置成只讀。舉個例子:

用 裝飾器即可將讀值方法標記成特性,只有將對象的屬性都設置成不可變,才能實現 方法。這個方法需要返回一個整數,且需要保證相等對象的散列值相同,所以最好的實現方式是使用異或運算來混合各屬性的散列值。我們來看看上面這個類的散列值:

Python 中有兩個特殊的裝飾器:classmethod、 staticmethod

classmethod :即類方法,是 Python 專用的。該裝飾器定義了該方法是操作類,而不是操作實例,因此類方法的第一個參數時類本身,而不是實例。按照約定,類方法的第一個參數名為 cls 。classmethod 最常見的用途是定義備選構造方法。

staticmethod:即靜態方法。該裝飾器也會改變方法的調用方式,但第一個參數不是特殊的值。靜態方法就是普通的函數,只是碰巧在類的定義體中,所以無法引用類或對象的屬性。

舉個例子看兩者的差別:

輸出結果:


在 Python 的底層實現中,類的所有對象的屬性都存在 屬性中,且所有對象的屬性共用 。

Python 不能像其他語言一樣用 修飾符來創建私有屬性,但是有一個簡單的機制來避免子類意外覆蓋私有屬性,即以 開頭來標記屬性私有化,比如上面例子中 和 屬性。這些私有屬性存入 中時,屬性名變為 + 類名 + 屬性名,比如 會變為 。這種語言特性稱為名稱改寫。

需要注意的是,Python 中不會使用單下劃線對屬性名做特殊處理,不過很多 Python 程序員會嚴格遵守 「不在類外部訪問這種屬性」 的約定。

在前面的博客中,我們講到了 Python 中字典的底層實現,字典的運算速度很快,但相當吃內存。而當類的屬性多到一定數量時,我們需要用到 屬性,來節省內存。


在 Python 中,唯一節省內存的數據結構是元組,所以 屬性的實現方法是讓解釋器在元組中存儲實例屬性,而不是字典。其定義十分簡單:

使用元組的形式也就意味著這些屬性不可變。有幾點需要注意的是:

每個子類都要定義 屬性,因為解釋器會忽略繼承該屬性;

對象只能擁有 中列出的屬性,除非將 加入其中;

用戶自定義的類中默認有 屬性,若想把對象作為弱引用的目標,需要把 也添加到 中。

如果使用得當, 屬性能顯著節省內存,而該屬性的存在是為了優化,不能用此作為限制用戶賦值的屬性。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

是時候配置一個Python3的開發環境了
用Python調用win命令行提高工作效率

TAG:Python |