寫在之前
在 Python 的類里面除了屬性之外,還有方法,當然也有文檔和注釋這類東西,但是這個只是人來看,計算機則不關心。我們之前說過,我們一般用實例調用方法,既然我們說了是一般,那么就說明還有其他調用方法的方式,今天我們就來說一下「綁定方法和非綁定方法」。
綁定方法和非綁定方法
在 Python 中除了特殊方法以外,類中的其他普通方法也是經常用到的,所以對于普通的方法也要進行研究,下面我們來看一個例子:
1
2
3
4
5
6
7
|
>>> class Sample: ... def f( self ): ... print ( 'f function is a normal method' ) ... >>> sam = Sample() >>> sam.f f function is a normal method |
從我們之前的學習中你知道,在類 sample 中,方法 f() 本質上是一個函數,只不過這個函數的第一個參數必須是 self,當然了,為了區別我們在類中給它起了另外的一個名字「方法」。但是跟函數相比,在本質上沒什么不同。
當創建了實例以后,我們在用實例調用這個方法的時候,因為 Python 解釋器已經把實例作為第一個參數隱式的傳給了該方法,所以 self 這個參數不需要顯式的寫出來,這個知識點我反復說了很多次,就是為了能讓大家理解 self 是實例!
如果想要把實例顯式的傳給方法,可以用下面的方式:
1
2
|
>>> Sample.f(sam) f function is a normal method |
用上述方法能更好的證明前面的觀點,即實例化以后,self 和實例 sam 是相同的。一般情況下我們再類里面使用 self,在類外面使用 sam,二者各有分工。
那如果我們在用類調用方法的時候,不傳實例會發生什么呢?
1
2
3
4
|
>>> Sample.f() Traceback (most recent call last): File "<stdin>" , line 1 , in <module> TypeError: unbound method f() must be called with Sample instance as first argument (got nothing instead) |
答案是會報錯,我們仔細看一下是因為缺少了一個參數,它是一個實例,所以我們要傳一個實例。
Python 中的一切都是對象,所以類 Sample 的方法 f() 也是對象,具體點說是一個函數對象,那么我們可以像下面這樣來獲得該對象:
1
2
|
>>> Sample.f <function Sample.f at 0x000000000244AB48 > |
當然我們也可以通過實例來獲得對象:
1
2
|
>>> sam.f <bound method Sample.f of <__main__.sample instance at 0x000000000244AB48 >> |
上面用實例來得到這個方法對象,在這里我們看到是「綁定方法」(bound method)。
下面就要逐漸接近 “綁定方法” 和 “非綁定方法” 的概念本質了。
在類 Sample 的屬性中,有一個叫 __dict__ 的屬性方法,我們在前面的文章中也介紹過,我們接下來就用它來看一下類的內部信息:
1
2
|
>>> sample.__dict__[ 'f' ] <function f at 0x000000000250D828 > |
從上面來看,可以近一步的說明 f 是一個函數對象。
接下來讓我們學習一個新的知識叫做「描述器」,那么什么是描述器呢?在 Python 中有幾個比較特殊的特殊方法,分別是 __get__(),__set__() 和 __delete__(),稍微簡單點來說,有這些特殊方法的對象就叫做「描述器」。
描述器在 Python 中使用廣泛,如果你還記得我講過的 super,它是屬性,實例方法,繼承等使用 super 的背后實現機制。關于描述器的內容,在這做具體的說明,在這里提到它,純粹是為了解決綁定方法和非綁定方法的問題。所以如果你有興趣的話,可以自行 Google。
我們在這里僅看一下 __get__() ,關于它的所謂的描述器協議如下:
1
|
des.__get__( self ,obj, type = None ) - - - > value |
具體應用到上面的那個例子則是如下操作:
1
2
|
>>> sample.__dict__[ 'f' ].__get__(sam,sample) <bound method sample.f of <__main__.sample instance at 0x000000000244AB48 >> |
你可以發現上面顯示的結果和 sam.f 是一樣的。所以綜上,我們可以認為:當通過類來獲取方法的時候,得到的是非綁定方法對象;當通過實例來獲取方法的時候,得到的是綁定方法對象。
寫在之后
綁定方法和非綁定方法到這就結束了,類的方法可分為不少,除了綁定方法和非綁定方法以外,還有靜態方法和類方法等,我會在接下來依次的進行介紹,敬請期待。
寫出來的東西是我的,看進去的東西才是你的,希望你不要浪費自己的時間,要學有所得。如果你覺得文章對你有幫助的話,歡迎你點贊轉發,謝謝支持。
The end。
以上就是詳解python方法之綁定方法與非綁定方法的詳細內容,更多關于python 綁定方法與非綁定方法的資料請關注服務器之家其它相關文章!
原文鏈接:https://cloud.tencent.com/developer/article/1534426