Looking up the information, basically there are three ways to determine whether a python object is a callable function or not
Using the built-in callable function
callable(func)
Used to check whether the object can be called, return True may also fail to call, but return False must not be called.
Official Documentation:/3/library/?highlight=callable#callable
Determine if an object type is a FunctionType.
type(func) is FunctionType # Or isinstance(func, FunctionType)
Determine whether an object implements the __call__ method.
hasattr(func, '__call__')
Write a small demo to test the difference between these three authentication methods
from types import FunctionType __author__ = 'blackmatrix' class ClassA: @staticmethod def func_a(): pass @classmethod def func_b(cls, arg): pass def func_c(self, arg): pass def func_d(): pass if __name__ == '__main__': class_a = ClassA() print('Static methods, instance call validation') print("callable(class_a.func_a) result: {result}".format(result=callable(class_a.func_a))) print("type(class_a.func_a) is FunctionType result: {result}".format(result=type(class_a.func_a) is FunctionType)) print("hasattr(class_a.func_a, '__call__') result: {result}".format(result=hasattr(class_a.func_a, '__call__'))) print('Static methods, class call validation') print("callable(ClassA.func_a) result: {result}".format(result=callable(ClassA.func_a))) print("type(ClassA.func_a) is FunctionType result: {result}".format(result=type(ClassA.func_a) is FunctionType)) print("hasattr(ClassA.func_a, '__call__') result: {result}".format(result=hasattr(ClassA.func_a, '__call__'))) print('Class method validation') print("callable(ClassA.func_b) result: {result}".format(result=callable(ClassA.func_b))) print("type(ClassA.func_b) is FunctionType result: {result}".format(result=type(ClassA.func_b) is FunctionType)) print("hasattr(ClassA.func_b, '__call__') result: {result}".format(result=hasattr(ClassA.func_b, '__call__'))) print('Instance method validation') print("callable(class_a.func_c) result: {result}".format(result=callable(class_a.func_c))) print("type(class_a.func_c) is FunctionType result: {result}".format(result=type(class_a.func_c) is FunctionType)) print("hasattr(class_a.func_c, '__call__') result: {result}".format(result=hasattr(class_a.func_c, '__call__'))) print('Function Validation') print("callable(func_d) result: {result}".format(result=callable(func_d))) print("type(func_d) is FunctionType result: {result}".format(result=type(func_d) is FunctionType)) print("hasattr(func_d, '__call__') result: {result}".format(result=hasattr(func_d, '__call__')))
By running the results, it was found that the validation results of the three methods were not the same.
Mainly the type(func) is FunctionType method, which returns False when validating class methods against instance methods.
From the debugging result, the type of instance method, and class method are <class 'method'>, not FunctionType, so it will return False.
static method,Instance call validation callable(class_a.func_a) result: True type(class_a.func_a) is FunctionType result: True hasattr(class_a.func_a, '__call__') result: True static method,Class call validation callable(ClassA.func_a) result: True type(ClassA.func_a) is FunctionType result: True hasattr(ClassA.func_a, '__call__') result: True Class Method Validation callable(ClassA.func_b) result: True type(ClassA.func_b) is FunctionType result: False hasattr(ClassA.func_b, '__call__') result: True Instance Method Validation callable(class_a.func_c) result: True type(class_a.func_c) is FunctionType result: False hasattr(class_a.func_c, '__call__') result: True function verification callable(func_d) result: True type(func_d) is FunctionType result: True hasattr(func_d, '__call__') result: True
Because Python is divided into function (function) and method (method), function is a callable object in Python (user-defined callable objects, and functions created by lambda expressions, are functions, whose type is FunctionType), and method is a special kind of class function.
Definition of method in the official documentation:
Methods are always bound to an instance of a user-defined class
Class methods are bound to classes and instance methods are bound to instances, so both are of type method.
Static methods, on the other hand, are not bound to classes or instances, and do not meet the above definition, so their type should be function.
One of the other things to note is that if a class implements the __call__ method, then its instance also becomes a callable object of the type of the class that created it, rather than a function or method.
class TheClass: def __call__(self, *args, **kwargs): return self if __name__ == '__main__': the_class = TheClass() # True print('class_instance callable {callable} '.format(callable=callable(the_class)))
So to determine whether a Python object is callable by type, you need to determine both whether it is a function (FunctionType) or a method (MethodType), or whether the class implements the __call__ method.
If you are simply determining whether a python object is callable or not, it would be more prudent to use the callable() method.
The above three ways of determining whether a python object is callable and their differences in detail is all that I have shared with you, and I hope it will give you a reference, and I hope you will support me more.