Python中的函數(shù)(function)與方法(method)使用詳解
在編程語言中有兩個(gè)很基礎(chǔ)的概念,即方法(method)和函數(shù)(function)。
除去入?yún)?、返回值、匿名函?shù)之類的正確的形式內(nèi)容之外,我們一般都會這樣說:“函數(shù)就是定義在類外面的,而方法就是定義在類里面的,跟類綁定的”
深究一下
判斷是函數(shù)(function)還是方法(method)
在標(biāo)準(zhǔn)庫inspect 中,它提供了兩個(gè)自省的函數(shù),即 ismethod() 和 isfunction(),可以用來判斷什么是方法,什么是函數(shù)。
import inspect
def test1():
print('這是方法還是函數(shù)?')
print(inspect.isfunction(test1)) # True
print(inspect.ismethod(test1)) # False
運(yùn)行的結(jié)果分別是“True”和“False”,表明我們所定義的 test() 是一個(gè)函數(shù),而不是一個(gè)方法。
注意:不能用這種方式,這種方式會調(diào)用函數(shù)
import inspect
def test1():
print('這是方法還是函數(shù)?')
print(inspect.isfunction(test1()))
# 輸出結(jié)果
這是方法還是函數(shù)?
False
inspect.ismethod() 與 inspect.isfunction()
這兩個(gè)函數(shù)也可以用來檢測自身,不難驗(yàn)證出它們都是一種函數(shù)
import inspect print(inspect.isfunction(inspect.ismethod)) # True print(inspect.isfunction(inspect.isfunction)) # True
那么,inspect 庫的兩個(gè)函數(shù)是什么工作原理呢?
看看源碼,將鼠標(biāo)光標(biāo)處放在要查看的內(nèi)容上,按住Ctrl并單擊鼠標(biāo)左鍵,進(jìn)入源碼查看


通過 isfunction() 和 ismethod() 的注釋,我們可以得到以下結(jié)論:
- 非用戶定義的函數(shù),即內(nèi)置函數(shù),在 isfunction() 眼里并不是“函數(shù)”(FunctionType)!
下面驗(yàn)證一下 len()、 range():
import inspect print(inspect.isfunction(len)) # False print(inspect.isfunction(range)) # False
可以發(fā)現(xiàn),它們的本質(zhì)并不是函數(shù),事實(shí)上,它們有專屬的類別(BuiltinFunctionType、BuiltinMethodType)
print(type(len)) 輸出結(jié)果: <class 'builtin_function_or_method'>
內(nèi)置函數(shù)都是builtin_function_or_method 類型
- 一個(gè)類的靜態(tài)方法,在 ismethod() 眼里并不是方法(MethodType)!
class MyTest():
@classmethod
def cls_func(cls):
pass
def ins_func(self):
pass
@staticmethod
def sta_func():
pass
print(inspect.ismethod(MyTest.cls_func)) # True
print(inspect.ismethod(MyTest.ins_func)) # False
print(inspect.ismethod(MyTest.sta_func)) # False
創(chuàng)建了類的實(shí)例后,再看看
test = MyTest() print(inspect.ismethod(test.cls_func)) # True print(inspect.ismethod(test.ins_func)) # True print(inspect.ismethod(test.sta_func)) # False
可以看出,除了 classmethod 之外,只有類實(shí)例的實(shí)例方法,才會被 ismethod() 判定為真!而靜態(tài)方法,不管綁定在類還是實(shí)例上,都不算是“方法”!
在源碼中,出現(xiàn)了 isinstance() 函數(shù),它主要用于判斷一個(gè)對象(object)是否是某個(gè)類(class)的實(shí)例(instance)。
還出現(xiàn)了 types.FunctionType 及types.MethodType ,它們指的就是目標(biāo)類。繼續(xù)點(diǎn)進(jìn)去看源碼



經(jīng)過簡化處理后,最關(guān)鍵是在于:通過type() 函數(shù)判斷出一個(gè)對象是 function 或 method 類,instance() 函數(shù)判斷出一個(gè)對象是否為某個(gè)類的實(shí)例
所以
isfunction() 判斷出的是用戶定義的函數(shù)(user-defined function), 它擁有__doc__、__name__ 等等屬性 ismethod() 判斷出的是實(shí)例方法(instance method), 它擁有函數(shù)的一些屬性,最特別的是還有一個(gè) __self__ 屬性
若以 inspect 庫的兩個(gè)函數(shù)為判斷依據(jù),則 Python 中的“方法與函數(shù)”具有一定的狹義性。
在判斷什么是函數(shù)時(shí),它們并不把內(nèi)置函數(shù)計(jì)算在內(nèi)。同時(shí),在判斷什么是方法時(shí),并非定義在類內(nèi)部的都算,而是只有類方法及綁定了實(shí)例的實(shí)例方法才算是“方法”。
也許你會說,inspect 的兩個(gè)判斷函數(shù)并不足信,規(guī)矩是寫死的,也有不靈活的時(shí)候,內(nèi)置函數(shù)也應(yīng)該算是“函數(shù)”,類里面的所有方法都應(yīng)該算是“方法”。
這種說法在廣義上是可接受的,畢竟我們一直叫的就是“XX函數(shù)”、而不會去說“XX方法”。
但是,理論和廣義概念只是方便人們的溝通理解,而代碼實(shí)現(xiàn)才是本質(zhì)的區(qū)別。
也就是說,Python 在實(shí)際區(qū)別“方法與函數(shù)”時(shí),文中開頭所說:“函數(shù)就是定義在類外面的,而方法就是定義在類里面的,跟類綁定的”,這句話并沒有錯(cuò),但其中的細(xì)節(jié)還是值得關(guān)注的。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Python內(nèi)置函數(shù)之def function_name函數(shù)解讀
- 詳解Python中的偏函數(shù)(Partial Functions)
- python人工智能tensorflow常用激活函數(shù)Activation?Functions
- Python偏函數(shù)Partial function使用方法實(shí)例詳解
- Python內(nèi)置函數(shù)之classmethod函數(shù)使用詳解
- Python內(nèi)置函數(shù)之staticmethod函數(shù)使用及說明
- Python中@classmethod和@staticmethod的區(qū)別
相關(guān)文章
Python的numpy庫下的幾個(gè)小函數(shù)的用法(小結(jié))
這篇文章主要介紹了Python的numpy庫下的幾個(gè)小函數(shù)的用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
python網(wǎng)絡(luò)爬蟲之如何偽裝逃過反爬蟲程序的方法
本篇文章主要介紹了python網(wǎng)絡(luò)爬蟲之如何偽裝逃過反爬蟲程序的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11
PyTorch中dataloader制作自定義數(shù)據(jù)集的實(shí)現(xiàn)示例
本文主要介紹了PyTorch中dataloader制作自定義數(shù)據(jù)集的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-05-05
手把手教你pycharm專業(yè)版安裝破解教程(linux版)
這篇文章主要介紹了 手把手教你pycharm專業(yè)版安裝破解教程(linux版),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
Python中os.path.join函數(shù)的用法示例詳解
這篇文章主要給大家介紹了關(guān)于Python中os.path.join函數(shù)用法的相關(guān)資料,os.path.join函數(shù)是Python標(biāo)準(zhǔn)庫中的一個(gè)函數(shù),用于將多個(gè)路徑組合成一個(gè)有效的路徑,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
Python實(shí)現(xiàn)基于PIL和tesseract的驗(yàn)證碼識別功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)基于PIL和tesseract的驗(yàn)證碼識別功能,結(jié)合實(shí)例形式分析了Python使用PIL與tesseract進(jìn)行驗(yàn)證碼識別操作的具體技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2018-07-07

