如何判斷一個對象是否是可調用對象


基本上判斷python對象是否為可調用的函數,有三種方法:

1、使用內置的callable函數

callable(func)

用於檢查對象是否可調用,返回True也可能調用失敗,但是返回False一定不可調用

2、判斷對象類型是否是FunctionType

type(func) is FunctionType
# 或者
isinstance(func, FunctionType)

3、判斷對象是否實現__call__方法

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()方法會更穩妥。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM