基本上判斷python對象是否爲可調用的函數,有三種方法:python
一、使用內置的callable函數函數
callable(func)
用於檢查對象是否可調用,返回True也可能調用失敗,可是返回False必定不可調用spa
二、判斷對象類型是不是FunctionType調試
type(func) is FunctionType # 或者 isinstance(func, FunctionType)
三、判斷對象是否實現__call__方法code
hasattr(func, '__call__')
例子:對象
# 三種驗證方式的區別 from types import FunctionType class A(object): @staticmethod def f1(): return 'from f1' @classmethod def f2(cls,*arg): return 'from f2' def f3(self,*arg): return 'from f3' def f4(): pass if __name__ == '__main__': a=A() print('靜態方法,實例調用驗證') print(callable(a.f1)) # True print(type(a.f1) is FunctionType) # True print(hasattr(a.f1,'__call__')) # True print('靜態方法,類調用驗證') print(callable(a.f2)) # True print(type(a.f2) is FunctionType) # False print(hasattr(a.f2,'__call__')) # True print('類方法驗證') print(callable(A.f3)) # True print(type(A.f3) is FunctionType) # True print(hasattr(A.f3,'__call__')) # True print('實例方法驗證') print(callable(a.f3)) # True print(type(a.f3) is FunctionType) # False print(hasattr(a.f3, '__call__')) # True print('函數驗證') print(callable(f4)) # True print(type(f4) is FunctionType) # True print(hasattr(f4,'__call__')) # True """ 經過運行結果,發現三種方法的驗證結果並不相同。 主要是type(func) is FunctionType方法,在驗證類方法和實例方法時,會返回False, 從調試的結果上看,實例方法,和類方法的類型都是<class 'method'>,不是FunctionType,因此會返回False。 """
python中分爲函數(function)和方法(method),函數是python中一個可調用對象(用戶定義的可調用對象,及lambda表達式
建立的函數,都是函數,其類型都是FunctionType),方法是一種特殊的類函數。
官方文檔中,對於method的定義:
Methods are always bound to an instance of a user-defined class
類方法和類進行綁定,實例方法與實例進行綁定,因此二者的類型都是method。
而靜態方法,自己即不和類綁定,也不和實例綁定,不符合上述定義,因此其類型應該是function。
其中還有須要注意的是,若是一個類實現了__call__方法,那麼其實例也會成爲一個可調用對象,其類型爲建立這個實例的類,而不是函數或方法。
class MyClass(object): def __call__(self, *args, **kwargs): return self if __name__ == '__main__': myclass=MyClass() print(callable(myclass)) # True
因此經過類型去判斷Python對象是否可調用,須要同時判斷是函數(FunctionType)仍是方法(MethodType),或者類是否實現__call__方法。若是隻是單純判斷python對象是否可調用,用callable()方法會更穩妥。