可調用對象,即任何可以通過函數操作符()來調用的對象。
python可調用對象大致可以分為4類:
1、函數
python中有三種函數:內建函數(BIFs)、用戶自定義函數(UDF)、lambda表達式
2、方法
和函數類似,方法也有內建方法(BIM)和用戶自定義方法(UDM)。用戶自定義方法是被定義為類的一部分的函數;內建方法,如一個python數據類型如列表和字典,也有方法,這些方法就叫做內建方法。
內建方法和內建函數不同之處在於,內建方法的__self__屬性指向一個python對象,而內建函數的__self__指向None
3、類
實例化
4、某些類的實例
python給類創建了__call__的特別方法,該方法允許程序員創建可調用的對象(實例)。默認情況下,__call__()是沒有實現的,即大多數的類的實例是不可調用的。而如果類中實現了這個方法,那么這個類的實例就成了可調用的了。
調用這樣的實例等同於調用__call__()方法。
這里主要講一下可調用實例的作用:
1、可以簡化對象下方法的調用
如foo 類實現了__call__()方法,那么調用 foo() 和調用foo.__call__()是一樣的。
這種使用與當對象下面只有一個方法的時候,或者對象下某個方法被使用很多次的情況下。
2、模糊了對象和函數的區別,這個具體有什么用呢?看個例子:
class A():
def get():
return object()
class B():
def run():
return object()
def foo():
return object()
上面創建了兩個類和一個函數,現在我需要定義main函數,接收一個參數,並得到object對象
def Main(param):
# 如果param為A
param.get()
# 如果param為B
param.run()
# 如果param為foo
param()
Main(A())
Main(B())
Main(foo)
要完成這個需求,通過上面三種方式去分別調用,且需要在main函數內部去判斷,當前調用的是哪個類
那么如果我把上面的三種情況換成可調用對象實例的方式去完成呢?
class A():
def __call__():
return object()
class B():
def __call__():
return object()
def foo():
return object()
這樣改寫后,同樣要實現上面的需求,我們需要怎么做呢?
def Main(callableFun):
callableFun()
Main(A())
Main(B())
Main(foo)
可以看到,在main函數內部,我們可以大大的簡化我們的代碼,不需要再針對的性的去做判斷,這就是可調用實例類的用處之一。