學(xué)編程這么久,還傻傻分不清什么是方法(method)鹃祖,什么是函數(shù)(function)溪椎?

orange-tabby-cat-1769642.jpg

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

也許在你心中已有答案了

除去入?yún)⒆婺堋⒎祷刂登革⒛涿瘮?shù)之類的正確的形式內(nèi)容之外,你也許會說“函數(shù)就是定義在類外面的养铸,而方法就是定義在類里面的雁芙,跟類綁定的”。

這種說法有沒有問題呢钞螟?當(dāng)然有兔甘!不然我就不會專門寫這篇文章了,本文主要會來厘清這個問題筛圆。

在標(biāo)準(zhǔn)庫inspect 中裂明,它提供了兩個自省的函數(shù),即 ismethod() 和 isfunction()太援,可以用來判斷什么是方法闽晦,什么是函數(shù)。

因此提岔,本文想要先來研究一下這兩個函數(shù)仙蛉,看看 Python 在處理方法/函數(shù)的概念時,是怎么做的碱蒙?

關(guān)于它們的用法荠瘪,先看一個最簡單的例子:

image

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

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

image

那么喷兼,接下來的問題是:inspect 庫的兩個函數(shù)是什么工作原理呢篮绰?

先來看看 inspect 中的實現(xiàn)代碼:

image
image

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

我們還看到了 types.FunctionTypetypes.MethodType 臀突,它們指的就是目標(biāo)類。繼續(xù)點進去看源碼:

# 摘自 types.py
def _f(): pass
FunctionType = type(_f)

class _C:
    def _m(self): pass
MethodType = type(_C()._m)

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

image

梳理它們的關(guān)系梳码,可以得到:

image

經(jīng)過簡化處理后,我們發(fā)現(xiàn)最關(guān)鍵的是兩個問題:type() 函數(shù)如何判斷出一個對象是 function 或 method 類困食?instance() 函數(shù)如何判斷出一個對象是某個類的實例边翁?

這兩個內(nèi)置函數(shù)都是用 C 語言實現(xiàn)的,這里我就不打算繼續(xù)深究了……

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

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

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

1焰坪、非用戶定義的函數(shù),即內(nèi)置函數(shù)聘惦,在 isfunction() 眼里并不是“函數(shù)”(FunctionType)某饰!

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

image

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

image
image

特別需要注意的是,內(nèi)置函數(shù)都是builtin_function_or_method 類型禀酱,但是 range()炬守、type()、list() 等看起來像是函數(shù)的剂跟,其實不然:

image

(PS:關(guān)于這點减途,我這篇文章 曾提到過,就不再展開了曹洽。)

2鳍置、一個類的靜態(tài)方法,在 ismethod() 眼里并不是方法(MethodType)送淆!

image

創(chuàng)建了類的實例后墓捻,再看看:

image

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

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

好了羽杰,回到本文開頭的問題,我們最后來小結(jié)一下吧到推。

若以 inspect 庫的兩個函數(shù)為判斷依據(jù)考赛,則 Python 中的“方法與函數(shù)”具有一定的狹義性。在判斷什么是函數(shù)時莉测,它們并不把內(nèi)置函數(shù)計算在內(nèi)颜骤。同時,在判斷什么是方法時捣卤,并非定義在類內(nèi)部的都算忍抽,而是只有類方法及綁定了實例的實例方法才算是“方法”。

也許你會說董朝,inspect 的兩個判斷函數(shù)并不足信鸠项,內(nèi)置函數(shù)也應(yīng)該算是“函數(shù)”,類里面的所有方法都應(yīng)該算是“方法”子姜。

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

但是牧抽,理論和廣義概念只是方便人們的溝通理解,而代碼實現(xiàn)才是本質(zhì)的區(qū)別扭弧。也就是說阎姥,Python 在實際區(qū)別“方法與函數(shù)”時,并不是文中開頭的簡單說法鸽捻,還有更多的細節(jié)值得關(guān)注呼巴。

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市厚满,隨后出現(xiàn)的幾起案子府瞄,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遵馆,死亡現(xiàn)場離奇詭異鲸郊,居然都是意外死亡,警方通過查閱死者的電腦和手機货邓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門秆撮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人换况,你說我怎么就攤上這事职辨。” “怎么了戈二?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵舒裤,是天一觀的道長。 經(jīng)常有香客問我觉吭,道長腾供,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任亏栈,我火速辦了婚禮台腥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绒北。我一直安慰自己黎侈,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布闷游。 她就那樣靜靜地躺著峻汉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脐往。 梳的紋絲不亂的頭發(fā)上休吠,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音业簿,去河邊找鬼瘤礁。 笑死,一個胖子當(dāng)著我的面吹牛梅尤,可吹牛的內(nèi)容都是我干的柜思。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼巷燥,長吁一口氣:“原來是場噩夢啊……” “哼赡盘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缰揪,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤陨享,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抛姑,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡赞厕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了定硝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坑傅。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖喷斋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蒜茴,我是刑警寧澤星爪,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站粉私,受9級特大地震影響顽腾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜诺核,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一抄肖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧窖杀,春花似錦漓摩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至桌硫,卻和暖如春夭咬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铆隘。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工卓舵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膀钠。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓掏湾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親托修。 傳聞我的和親對象是個殘疾皇子忘巧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容