Python (類)例項方法的特殊屬性

發表於2016-06-15

自定義函式的特殊屬性已經專門整理過一篇(Python 自定義函式的特殊屬性),方法的特殊屬性與其稍有不同,我們通過下面這個例子展開介紹:

例項方法的只讀屬性

與自定義函式的特殊屬性相比,例項方法具有 __self__,__func__ 這兩個函式所不具有的只讀屬性;此外,方法的 __doc__,__name__,__module__ 也是隻讀。對於例項方法而言,其 __self__ 屬性為例項本身:

__func__ 屬性則返回方法所對應的底層函式:

至於 __doc__,__name__,__module__ 屬性則與函式相應屬性的值一致,所不同的是方法的這些屬性均為只讀,不可改寫:

例項方法可通過底層函式訪問函式屬性

不過,例項方法也可以通過其底層的 function 物件(通過 __func__ 屬性獲得)訪問函式所具有的特殊屬性,如:

因此,諸如 __doc__,__name__,__module__等屬性的值就可以通過底層函式相應的特殊屬性進行改寫:

底層函式的唯一性

需要注意的是:當一個類的例項方法是通過其他例項方法建立,則其他例項方法所對應的底層函式並非其所建立的例項方法,而是其所建立的例項方法所對應的底層函式:

上例中,通過其他例項方法 a.bar 建立了例項方法 a.foo,但a.bar.__func__ 卻是 a.foo.__func__ 而非 a.foo

例項方法的首位引數為例項本身

例項方法執行時,其底層函式的首位引數為例項本身,下面兩行程式碼執行結果是一致的:

類例項方法的首位引數是類本身

當一個例項方法(嚴格來說是類例項方法)是由類方法建立,則其 __self__ 屬性是其類本身:

事實上,通過類方法建立的(類)例項方法,在呼叫底層函式時(下例是 A.clsmtd.__func__),其首位引數(也即 __self__)是類本身,這一點與例項方法執行時有所區別。

類例項方法,本身也是 bound method,這與例項方法一致:

只不過,一個是繫結類(類例項),另一個是繫結例項。

總結

  • Python 3 有兩種 bound method, 一種是 instance method,一種是 class methodclass instance method),兩種都可以被例項訪問;
  • 對於 instance method__self__ 屬性值為 instance 本身,而 class method 其屬性值則為 class 本身;
  • 不管是 instance method 還是 class method ,執行時,都需要呼叫與之對應的底層函式(underlying function,通過 __func__ 訪問),底層函式的首位引數通過 __self__ 獲得, 對於 instance method 其為該例項本身,對於 class method 則為該類本身;
  • bound method 可以通過對應的底層函式,訪問函式的所有特殊屬性。

相關文章