
你好,我是悅創。
在我啃代理池的時候呢,遇到了這個 @property 的裝飾器,但我确認對她沒有任何感覺,為此呢就不得不再去找資料啃這些知識點了,接下來我把我的個人心得傳授給你。
在 綁定屬性 時,如果我們直接把屬性暴露出去,雖然寫起來很簡單,但是,沒辦法檢查參數,導緻可以把成績随便改,比如如下代碼:
先進行正常的操作:
運作結果如下:
這顯然不合邏輯。為了限制 score 的範圍,可以通過一個<code>set_score()</code>方法來設定成績,再通過一個<code>get_score()</code>來擷取成績,這樣,在<code>set_score()</code>方法裡,就可以檢查參數:
還是上面的操作代碼:
運作結果:
這樣就隻能通過 set_score() 函數進行設定,并且我的 set_score() 函數限制了 <code>self._score</code> 值的大小。
是以當我們添加或者修改 <code>self._score</code> 的值時,滿足範圍的則不會報錯,不滿足範圍的則會報錯且這個報錯是我們自定義的。
代碼示例如下:
看到這裡很成功也很正常,這也是很多公衆号就寫到這或者根本不會這麼詳細,而你們也覺得懂了,這就問題很粗了。有個問題來了,不管你們有沒有想到其他公衆号故意避開問題來寫(或者是沒意識到)還是其他,我要把它提出了,我們把它的操作方法變成下面的代碼又可以成功操作了:
這裡要注意觀察我們在 score 前面加上了 <code>_</code> 也就是這個: <code>student._score</code> 成功修改值也指派,你把 <code>student.set_score(10)</code> 去掉也還是可以正常指派的。對于這個問題,我已經寫在我的部落格上面了,這裡就不做贅述了 1 。
現在,對任意的 Student 執行個體進行操作,就不能随心所欲地設定 score 了:
但是,上面的調用方法又略顯複雜,沒有直接用屬性這麼直接簡單。
有沒有既能檢查參數,又可以用類似屬性這樣簡單的方式來通路類的變量呢?對于追求完美的 Python 程式員來說,這是必須要做到的!
還記得裝飾器(decorator)可以給函數動态加上功能嗎?對于類的方法,裝飾器一樣起作用。Python内置的<code>@property</code> 裝飾器就是負責把一個方法變成屬性調用的:
<code>@property</code> 的實作比較複雜,我們先考察如何使用。把一個 getter 方法變成屬性,隻需要加上 <code>@property</code> 就可以了,此時,<code>@property</code>本身又建立了另一個裝飾器<code>@score.setter</code>,負責把一個 setter 方法變成屬性指派,于是,我們就擁有一個可控的屬性操作:
注意到這個神奇的 <code>@property</code> ,我們在對執行個體屬性操作的時候,就知道該屬性很可能不是直接暴露的,而是通過getter 和 setter 方法來實作的。
還可以定義隻讀屬性,隻定義 getter 方法,不定義 setter 方法就是一個隻讀屬性:
上面的<code>birth</code>是可讀寫屬性,而<code>age</code>就是一個隻讀屬性,因為<code>age</code>可以根據<code>birth</code>和目前時間計算出來。
<code>@property</code>廣泛應用在類的定義中,可以讓調用者寫出簡短的代碼,同時保證對參數進行必要的檢查,這樣,程式運作時就減少了出錯的可能性。
https://www.aiyc.top/archives/550.html ↩︎