Python判断一个对象是否为函数或方法
2021/11/3 20:41:48
本文主要是介绍Python判断一个对象是否为函数或方法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 问题描述
- 解决方案
- 对比
- 耗时
- 参考文献
问题描述
Python判断一个对象是否为函数
解决方案
callable(x)
hasattr(x, '__call__')
inspect.isfunction(x)
inspect.ismethod(x)
inspect.isgeneratorfunction(x)
inspect.iscoroutinefunction(x)
inspect.isasyncgenfunction(x)
isinstance(x, typing.Callable)
isinstance(x, types.BuiltinFunctionType)
isinstance(x, types.BuiltinMethodType)
isinstance(x, types.FunctionType)
isinstance(x, types.MethodType)
isinstance(x, types.LambdaType)
isinstance(x, functools.partial)
import types import inspect import functools import typing def judge(x): name = x.__name__ if hasattr(x, '__name__') else 'functools.partial' print(name) print('\ttype({})={}'.format(name, type(x))) print('\tcallable({})={}'.format(name, callable(x))) print('\thasattr({}, \'__call__\')={}'.format(name, hasattr(x, '__call__'))) print() print('\tinspect.isfunction({})={}'.format(name, inspect.isfunction(x))) print('\tinspect.ismethod({})={}'.format(name, inspect.ismethod(x))) print('\tinspect.isgeneratorfunction({})={}'.format(name, inspect.isgeneratorfunction(x))) print('\tinspect.iscoroutinefunction({})={}'.format(name, inspect.iscoroutinefunction(x))) print('\tinspect.isasyncgenfunction({})={}'.format(name, inspect.isasyncgenfunction(x))) print() print('\tisinstance({}, typing.Callable)={}'.format(name, isinstance(x, typing.Callable))) print('\tisinstance({}, types.BuiltinFunctionType)={}'.format(name, isinstance(x, types.BuiltinFunctionType))) print('\tisinstance({}, types.BuiltinMethodType)={}'.format(name, isinstance(x, types.BuiltinMethodType))) print('\tisinstance({}, types.FunctionType)={}'.format(name, isinstance(x, types.FunctionType))) print('\tisinstance({}, types.MethodType)={}'.format(name, isinstance(x, types.MethodType))) print('\tisinstance({}, types.LambdaType)={}'.format(name, isinstance(x, types.LambdaType))) print('\tisinstance({}, functools.partial)={}'.format(name, isinstance(x, functools.partial))) def func(a, b): pass partial = functools.partial(func, a=1) _lambda = lambda _: _ def generator(): yield 1 yield 2 async def async_func(): pass async def async_generator(): yield 1 class A: def __call__(self, a, b): pass def func1(self, a, b): pass @classmethod def func2(cls, a, b): pass @staticmethod def func3(a, b): pass for func in [print, func, partial, _lambda, generator, async_func, async_generator, A, A.func1, A.func2, A.func3]: judge(func)
结果
print type(print)=<class 'builtin_function_or_method'> callable(print)=True hasattr(print, '__call__')=True inspect.isfunction(print)=False inspect.ismethod(print)=False inspect.isgeneratorfunction(print)=False inspect.iscoroutinefunction(print)=False inspect.isasyncgenfunction(print)=False isinstance(print, typing.Callable)=True isinstance(print, types.BuiltinFunctionType)=True isinstance(print, types.BuiltinMethodType)=True isinstance(print, types.FunctionType)=False isinstance(print, types.MethodType)=False isinstance(print, types.LambdaType)=False isinstance(print, functools.partial)=False func type(func)=<class 'function'> callable(func)=True hasattr(func, '__call__')=True inspect.isfunction(func)=True inspect.ismethod(func)=False inspect.isgeneratorfunction(func)=False inspect.iscoroutinefunction(func)=False inspect.isasyncgenfunction(func)=False isinstance(func, typing.Callable)=True isinstance(func, types.BuiltinFunctionType)=False isinstance(func, types.BuiltinMethodType)=False isinstance(func, types.FunctionType)=True isinstance(func, types.MethodType)=False isinstance(func, types.LambdaType)=True isinstance(func, functools.partial)=False functools.partial type(functools.partial)=<class 'functools.partial'> callable(functools.partial)=True hasattr(functools.partial, '__call__')=True inspect.isfunction(functools.partial)=False inspect.ismethod(functools.partial)=False inspect.isgeneratorfunction(functools.partial)=False inspect.iscoroutinefunction(functools.partial)=False inspect.isasyncgenfunction(functools.partial)=False isinstance(functools.partial, typing.Callable)=True isinstance(functools.partial, types.BuiltinFunctionType)=False isinstance(functools.partial, types.BuiltinMethodType)=False isinstance(functools.partial, types.FunctionType)=False isinstance(functools.partial, types.MethodType)=False isinstance(functools.partial, types.LambdaType)=False isinstance(functools.partial, functools.partial)=True <lambda> type(<lambda>)=<class 'function'> callable(<lambda>)=True hasattr(<lambda>, '__call__')=True inspect.isfunction(<lambda>)=True inspect.ismethod(<lambda>)=False inspect.isgeneratorfunction(<lambda>)=False inspect.iscoroutinefunction(<lambda>)=False inspect.isasyncgenfunction(<lambda>)=False isinstance(<lambda>, typing.Callable)=True isinstance(<lambda>, types.BuiltinFunctionType)=False isinstance(<lambda>, types.BuiltinMethodType)=False isinstance(<lambda>, types.FunctionType)=True isinstance(<lambda>, types.MethodType)=False isinstance(<lambda>, types.LambdaType)=True isinstance(<lambda>, functools.partial)=False generator type(generator)=<class 'function'> callable(generator)=True hasattr(generator, '__call__')=True inspect.isfunction(generator)=True inspect.ismethod(generator)=False inspect.isgeneratorfunction(generator)=True inspect.iscoroutinefunction(generator)=False inspect.isasyncgenfunction(generator)=False isinstance(generator, typing.Callable)=True isinstance(generator, types.BuiltinFunctionType)=False isinstance(generator, types.BuiltinMethodType)=False isinstance(generator, types.FunctionType)=True isinstance(generator, types.MethodType)=False isinstance(generator, types.LambdaType)=True isinstance(generator, functools.partial)=False async_func type(async_func)=<class 'function'> callable(async_func)=True hasattr(async_func, '__call__')=True inspect.isfunction(async_func)=True inspect.ismethod(async_func)=False inspect.isgeneratorfunction(async_func)=False inspect.iscoroutinefunction(async_func)=True inspect.isasyncgenfunction(async_func)=False isinstance(async_func, typing.Callable)=True isinstance(async_func, types.BuiltinFunctionType)=False isinstance(async_func, types.BuiltinMethodType)=False isinstance(async_func, types.FunctionType)=True isinstance(async_func, types.MethodType)=False isinstance(async_func, types.LambdaType)=True isinstance(async_func, functools.partial)=False async_generator type(async_generator)=<class 'function'> callable(async_generator)=True hasattr(async_generator, '__call__')=True inspect.isfunction(async_generator)=True inspect.ismethod(async_generator)=False inspect.isgeneratorfunction(async_generator)=False inspect.iscoroutinefunction(async_generator)=False inspect.isasyncgenfunction(async_generator)=True isinstance(async_generator, typing.Callable)=True isinstance(async_generator, types.BuiltinFunctionType)=False isinstance(async_generator, types.BuiltinMethodType)=False isinstance(async_generator, types.FunctionType)=True isinstance(async_generator, types.MethodType)=False isinstance(async_generator, types.LambdaType)=True isinstance(async_generator, functools.partial)=False A type(A)=<class 'type'> callable(A)=True hasattr(A, '__call__')=True inspect.isfunction(A)=False inspect.ismethod(A)=False inspect.isgeneratorfunction(A)=False inspect.iscoroutinefunction(A)=False inspect.isasyncgenfunction(A)=False isinstance(A, typing.Callable)=True isinstance(A, types.BuiltinFunctionType)=False isinstance(A, types.BuiltinMethodType)=False isinstance(A, types.FunctionType)=False isinstance(A, types.MethodType)=False isinstance(A, types.LambdaType)=False isinstance(A, functools.partial)=False func1 type(func1)=<class 'function'> callable(func1)=True hasattr(func1, '__call__')=True inspect.isfunction(func1)=True inspect.ismethod(func1)=False inspect.isgeneratorfunction(func1)=False inspect.iscoroutinefunction(func1)=False inspect.isasyncgenfunction(func1)=False isinstance(func1, typing.Callable)=True isinstance(func1, types.BuiltinFunctionType)=False isinstance(func1, types.BuiltinMethodType)=False isinstance(func1, types.FunctionType)=True isinstance(func1, types.MethodType)=False isinstance(func1, types.LambdaType)=True isinstance(func1, functools.partial)=False func2 type(func2)=<class 'method'> callable(func2)=True hasattr(func2, '__call__')=True inspect.isfunction(func2)=False inspect.ismethod(func2)=True inspect.isgeneratorfunction(func2)=False inspect.iscoroutinefunction(func2)=False inspect.isasyncgenfunction(func2)=False isinstance(func2, typing.Callable)=True isinstance(func2, types.BuiltinFunctionType)=False isinstance(func2, types.BuiltinMethodType)=False isinstance(func2, types.FunctionType)=False isinstance(func2, types.MethodType)=True isinstance(func2, types.LambdaType)=False isinstance(func2, functools.partial)=False func3 type(func3)=<class 'function'> callable(func3)=True hasattr(func3, '__call__')=True inspect.isfunction(func3)=True inspect.ismethod(func3)=False inspect.isgeneratorfunction(func3)=False inspect.iscoroutinefunction(func3)=False inspect.isasyncgenfunction(func3)=False isinstance(func3, typing.Callable)=True isinstance(func3, types.BuiltinFunctionType)=False isinstance(func3, types.BuiltinMethodType)=False isinstance(func3, types.FunctionType)=True isinstance(func3, types.MethodType)=False isinstance(func3, types.LambdaType)=True isinstance(func3, functools.partial)=False
对比
判断方法 | callable(x) | hasattr(x, ‘__call__’) | inspect.isfunction(x) | inspect.ismethod(x) | inspect.isgeneratorfunction(x) | inspect.iscoroutinefunction(x) | inspect.isasyncgenfunction(x) | isinstance(x, typing.Callable) | isinstance(x, types.BuiltinFunctionType) | isinstance(x, types.BuiltinMethodType) | isinstance(x, types.FunctionType) | isinstance(x, types.MethodType) | isinstance(x, types.LambdaType) | isinstance(x, functools.partial) |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
√ | √ | × | × | × | × | × | √ | √ | √ | × | × | × | × | |
func | √ | √ | √ | × | × | × | × | √ | × | × | √ | × | √ | × |
functools.partial | √ | √ | × | × | × | × | × | √ | × | × | × | × | × | √ |
<lambda> | √ | √ | √ | × | × | × | × | √ | × | × | √ | × | √ | × |
generator | √ | √ | √ | × | √ | × | × | √ | × | × | √ | × | √ | × |
async_func | √ | √ | √ | × | × | √ | × | √ | × | × | √ | × | √ | × |
async_generator | √ | √ | √ | × | × | × | √ | √ | × | × | √ | × | √ | × |
A | √ | √ | × | × | × | × | × | √ | × | × | × | × | × | × |
func1 | √ | √ | √ | × | × | × | × | √ | × | × | √ | × | √ | × |
func2 | √ | √ | × | √ | × | × | × | √ | × | × | × | √ | × | × |
func3 | √ | √ | √ | × | × | × | × | √ | × | × | √ | × | √ | × |
import types import inspect import functools import typing def func(a, b): pass partial = functools.partial(func, a=1) _lambda = lambda _: _ def generator(): yield 1 yield 2 async def async_func(): pass async def async_generator(): yield 1 class A: def __call__(self, a, b): pass def func1(self, a, b): pass @classmethod def func2(cls, a, b): pass @staticmethod def func3(a, b): pass def judge(x): results = [ callable(x), hasattr(x, '__call__'), inspect.isfunction(x), inspect.ismethod(x), inspect.isgeneratorfunction(x), inspect.iscoroutinefunction(x), inspect.isasyncgenfunction(x), isinstance(x, typing.Callable), isinstance(x, types.BuiltinFunctionType), isinstance(x, types.BuiltinMethodType), isinstance(x, types.FunctionType), isinstance(x, types.MethodType), isinstance(x, types.LambdaType), isinstance(x, functools.partial) ] return results funcs = [ print, func, partial, _lambda, generator, async_func, async_generator, A, A.func1, A.func2, A.func3 ] judge_names = [ 'callable(x)', 'hasattr(x, \'__call__\')', 'inspect.isfunction(x)', 'inspect.ismethod(x)', 'inspect.isgeneratorfunction(x)', 'inspect.iscoroutinefunction(x)', 'inspect.isasyncgenfunction(x)', 'isinstance(x, typing.Callable)', 'isinstance(x, types.BuiltinFunctionType)', 'isinstance(x, types.BuiltinMethodType)', 'isinstance(x, types.FunctionType)', 'isinstance(x, types.MethodType)', 'isinstance(x, types.LambdaType)', 'isinstance(x, functools.partial)' ] print('|判断方法|{}|'.format('|'.join(judge_names))) print('|--' * (1 + len(judge_names)) + '|') for x in funcs: func_name = x.__name__ if hasattr(x, '__name__') else 'functools.partial' results = judge(x) results = ['√' if i else '×' for i in results] print('|{}|{}|'.format(func_name, '|'.join(results)))
耗时
挑选最通用的三种方法:
callable(x)
hasattr(x, '__call__')
isinstance(x, typing.Callable)
函数 | 耗时/s |
---|---|
callable(x) | 0.86 |
hasattr(x, ‘__call__’) | 1.36 |
isinstance(x, typing.Callable) | 12.19 |
import typing from timeit import timeit def x(): pass def f1(): return callable(x) def f2(): return hasattr(x, '__call__') def f3(): return isinstance(x, typing.Callable) print(timeit(f1, number=10000000)) print(timeit(f2, number=10000000)) print(timeit(f3, number=10000000)) # 0.8643081 # 1.3563508 # 12.193492500000001
参考文献
- How do I detect whether a Python variable is a function?
- Python快速计算函数耗时timeit
这篇关于Python判断一个对象是否为函数或方法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-25Python编程基础:变量与类型
- 2024-11-25Python编程基础与实践
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南
- 2024-11-16`PyMuPDF4LLM`:提取PDF数据的神器