滴滴,老Amy來啦~之前做開發的時候,一直忙著趕項目,活脫脫的就是一個秉持著「能用就行原則」的工具人[哭了],至於那顆充滿十萬個為什麼的好奇心直接被忽略~各位請細品,如果老Amy直接在公司要問領導「為什麼同樣是 def 定義,會有函數與方法兩個名稱?」,暴脾氣的領導還不跳起來給我兩下?
這我也理解,畢竟這個問題這麼問,大家肯定會向我投來同情的目光並且告訴我:「啥~定義在類裡的函數叫方法,曉得不?臭Amy」,emm...我就在想,這句話有據可依嘛?於是魯迅上身:「從來如此,便對嗎?」
於是乎,今天老Amy就來跟大家一起嘮嘮這方法與函數「背後的故事」~
前身Python中的 inspect 模塊,提供了一系列的對對象進行類型檢查的函數,其中可以看到 ismethod() 與 isfunction() 函數,就是用來判斷什麼是方法(method),什麼是函數(funtion)的...[就這?別急]
首先來舉個慄子,我們直接定義一個函數test,使用 ismethod() 與 isfunction() 驗證 test 是方法還是函數,還是...成年人的世界我都要?
In [1]: import inspect
In [2]: def test():
...: print("welcome...")
...:
In [3]: inspect.ismethod(test)
Out[3]: False
In [4]: inspect.isfunction(test)
Out[4]: True
運行的結果分別是 False 和 True,說明這是一個函數而不是一個方法...emmm..那有的朋友就會說,這不跟我想的一樣嘛?那我們在命令行中來看看這兩個函數的源碼
ismethod真相
ismethod() 判斷出的是實例方法(instance method) ,最主要的是,它包含__self__屬性[介是類的]
But...類的內部定義的方法全都是真正意義上的方法(MethodType)嗎?
In [16]: class Demo(object):
...: def ins_func(self):
...: pass
...:
...: @classmethod
...: def cls_func(cls):
...: pass
...:
...: @staticmethod
...: def sta_func():
...: pass
...:
In [17]: inspect.ismethod(Demo.ins_func)
Out[17]: False
In [18]: inspect.ismethod(Demo.cls_func)
Out[18]: True
In [19]: inspect.ismethod(Demo.sta_func)
Out[19]: False
In [20]: d = Demo()
In [21]: inspect.ismethod(d.ins_func)
Out[21]: True
In [22]: inspect.ismethod(d.cls_func)
Out[22]: True
In [23]: inspect.ismethod(d.sta_func)
Out[23]: False
isfunction真相
看到 isfuntion() 所檢測的是用戶自定義函數(a user-defined function),我又開始揣測,我們使用過那麼多的Python內置函數,比如:len() 、range() 、 map()...都是啥?
In [7]: inspect.isfunction(len)
Out[7]: False
In [8]: inspect.isfunction(range)
Out[8]: False
In [9]: inspect.isfunction(map)
Out[9]: FalseIn [10]: type(len)
Out[10]: builtin_function_or_method
僅此而已嗎?[都怪我太年輕..,是啥類型分不清],我們需要注意的是 range()
、 map() 等都只是看起來像函數...實際上,看圖,它們都屬於 type
In [11]: type(range)
Out[11]: type
In [12]: type(map)
Out[12]: type
這是為啥呢?來看看官網說明文檔
上圖可以看到,Built-in Functions 裡面不僅僅只有 functions (內置函數),還有types (內置類)。也就是說,range(),map() 都是類~
「我擦..不會吧!咋整的全民誤會?」,很有必要的去看了看python2的說明文檔
這樣就很好理解了,官方在python3已經修正了python2的定義,但是我們已經習慣了全部都叫函數了呀~所以,就有了這些模稜兩可的叫法。
到這裡~老Amy好像有點暈車了~必須附上偶像的表情hhhhh,簡單的給大家做個總結叭~
總結方法函數
用戶自定義函數可通過 aspect.isfunction() 來驗證
Built-in Functions 包含 functions(內置函數)以及types(內置類)。
如:type(len) 是 builtin_function_or_method,type(range) 則是 type。
今日雞湯
今天的雞湯有點狠,但是我們都要在快生活[emmm..]當中找到平靜又有力量的自己,謝謝你看到這裡啦~不防再來個在看與關注叭~筆芯