日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在編程語言中有兩個很基礎的概念,即方法(method)和函數(function)。如果達到了編程初級/入門級水平,那么你肯定在心中已有了初步的答案。

除去入參、返回值、匿名函數之類的正確的形式內容之外,你也許會說“函數就是定義在類外面的,而方法就是定義在類里面的,跟類綁定的”。

這種說法有沒有問題呢?當然有!不然我就不會專門寫這篇文章了,本文主要會來厘清這個問題。

在標準庫inspect 中,它提供了兩個自省的函數,即 ismethod() 和 isfunction(),可以用來判斷什么是方法,什么是函數。

因此,本文想要先來研究一下這兩個函數,看看 Python 在處理方法/函數的概念時,是怎么做的?

關于它們的用法,先看一個最簡單的例子:

學編程傻傻分不清什么是方法(method)和函數(function)?

 

運行的結果分別是“True”和“False”,表明我們所定義的 test() 是一個函數,而不是一個方法。

這兩個函數也可以用來檢測自身,不難驗證出它們都是一種函數:

學編程傻傻分不清什么是方法(method)和函數(function)?

 

那么,接下來的問題是:inspect 庫的兩個函數是什么工作原理呢?

先來看看 inspect 中的實現代碼:

學編程傻傻分不清什么是方法(method)和函數(function)?

 


學編程傻傻分不清什么是方法(method)和函數(function)?

 

在源碼中,我們看到了 isinstance() 函數,它主要用于判斷一個對象(object)是否是某個類(class)的實例(instance)。

我們還看到了 types.FunctionType 及types.MethodType ,它們指的就是目標類。繼續點進去看源碼:

  
  # 摘自 types.py
  def _f(): pass
  FunctionType = type(_f)
  ?
  class _C:
      def _m(self): pass
  MethodType = type(_C()._m)

這里只是定義了兩個空的 _f() 和 _m(),然后就使用了內置的 type() 函數。所以,我們完全可以把它們摘出來,看看廬山真面目:

學編程傻傻分不清什么是方法(method)和函數(function)?

 

梳理它們的關系,可以得到:

學編程傻傻分不清什么是方法(method)和函數(function)?

 

經過簡化處理后,我們發現最關鍵的是兩個問題:type() 函數如何判斷出一個對象是 function 或 method 類?instance() 函數如何判斷出一個對象是某個類的實例?

這兩個內置函數都是用 C 語言實現的,這里我就不打算繼續深究了……

但是,讓我們再回頭看看 inspect 中的注釋,就會注意到一些端倪:

  • isfunction() 判斷出的是用戶定義的函數(user-defined function), 它擁有__doc__、__name__ 等等屬性
  • ismethod() 判斷出的是實例方法(instance method), 它擁有函數的一些屬性,最特別的是還有一個 __self__ 屬性

還是注釋更管用啊,由此我們能得到如下的推論:

1、非用戶定義的函數,即內置函數,在 isfunction() 眼里并不是“函數”(FunctionType)!

下面驗證一下 len()、dir() 和 range():

學編程傻傻分不清什么是方法(method)和函數(function)?

 

事實上,它們有專屬的類別(BuiltinFunctionType、BuiltinMethodType):

學編程傻傻分不清什么是方法(method)和函數(function)?

 


學編程傻傻分不清什么是方法(method)和函數(function)?

 

特別需要注意的是,內置函數都是builtin_function_or_method 類型,但是 range()、type()、list() 等看起來像是函數的,其實不然:

學編程傻傻分不清什么是方法(method)和函數(function)?

 

(PS:關于這點,我這篇文章 曾提到過,就不再展開了。)

2、一個類的靜態方法,在 ismethod() 眼里并不是方法(MethodType)!

學編程傻傻分不清什么是方法(method)和函數(function)?

 

創建了類的實例后,再看看:

學編程傻傻分不清什么是方法(method)和函數(function)?

 

可以看出,除了 classmethod 之外,只有類實例的實例方法,才會被 ismethod() 判定為真!而靜態方法,不管綁定在類還是實例上,都不算是“方法”!

有沒有覺得很不可思議(或者有點理不清了)?

好了,回到本文開頭的問題,我們最后來小結一下吧。

若以 inspect 庫的兩個函數為判斷依據,則 Python 中的“方法與函數”具有一定的狹義性。在判斷什么是函數時,它們并不把內置函數計算在內。同時,在判斷什么是方法時,并非定義在類內部的都算,而是只有類方法及綁定了實例的實例方法才算是“方法”。

也許你會說,inspect 的兩個判斷函數并不足信,內置函數也應該算是“函數”,類里面的所有方法都應該算是“方法”。

我承認這種說法在廣義上是可接受的,畢竟我們一直叫的就是“XX函數”、“XX方法”嘛。

但是,理論和廣義概念只是方便人們的溝通理解,而代碼實現才是本質的區別。也就是說,Python 在實際區別“方法與函數”時,并不是文中開頭的簡單說法,還有更多的細節值得關注。

看完本文,你有什么想法呢?歡迎一起交流。

分享到:
標簽:編程
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定