Python 可调用对象的类型判断
技术百科
舞夢輝影
发布时间:2026-01-27
浏览: 次 判断对象是否可调用应使用 callable():它专为此设计,通过检查 call 方法实现且覆盖所有可调用协议,比 isinstance(obj, Callable)、字符串匹配类型名或 hasattr(obj, '__call__') 更准确可靠。
判断对象是否可调用:用 callable() 最直接
Python 中最稳妥、最符合语义的判断方式就是 callable()。它专为此设计,内部检查对象是否实现了 __call__ 方法,且不依赖类型继承关系。
常见误区是用 isinstance(obj, collections.abc.Callable) —— 这看似“更类型安全”,但实际会漏判:自定义类只要定义了 __call__ 就可调用,却未必显式继承或注册到 Callable 抽象基类。
-
callable(lambda x: x)→True -
callable(len)→True -
callable(42)→False -
callable(type)→True(类本身可调用)
为什么不能只看类型名或 __class__.__name__
靠字符串匹配类型名(比如检查是否含 "function" 或 "method")极不可靠。很多可调用对象根本不是函数类型:
- 类实例(实现了
__call__)→ 类型是MyClass,不是"function" -
functools.partial对象 → 类型是functools.partial,不是"function" - 某些 C 扩展模块返回的 callable 对象 → 类型名可能无意义(如
"builtin_function_or_method"之外还有各种变体)
更关键的是:callable() 是唯一能覆盖所有 Python 可调用协议的判断入口,包括未来新增的可调用类型。
hasattr(obj, '__call__') 的陷阱
手动检查 __call__ 属性存在,看起来直观,但容易误判:
- 对象有
__call__属性但值为None或不可调用 →hasattr返回True,但实际调用会报TypeError - 某些对象动态删除或屏蔽了
__call__(虽少见,但协议允许)→hasattr可能返回False,而callable()仍正确返回False(它还会做可调用性验证) -
callable()在 CPython 中是原子操作,比hasattr+ 类型检查更轻量
简言之:hasattr(obj, '__call__') 是必要不充分条件;callable() 是充分必要条件。
在类型注解和静态检查中怎么处理
运行时用 callable(),但类型系统里需注意:
- 类型提示应优先用
typing.Callable或更具体的签名(如Callable[[int], str]),而非Any -
mypy等工具不会把callable(x)的结果作为类型守卫(即不会据此推断x是Callable) - 若需类型守卫,得用
typing.TypeGuard自定义(Python 3.10+),但日常逻辑判断仍推荐无副作用的callable()
运行时判断和类型系统是两套逻辑,混用容易出错。真正要“执行”前,只信 callable();写类型提示时,按接口契约来,别依赖运行时判断反推类型。
# 的是
# 会把
# 实现了
# python
# 自定义
# 而非
# 专为
# 就可
# 工具
# 对象
# int
# 字符串
# 接口
# 为什么
# function
# 继承
# len
# Lambda
# 会报
# 必要条件
# 只看
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- php485能和物联网模块通信吗_php485对接
- 如何使用Golang benchmark测量函数延
- 如何使用正则表达式批量替换重复的星号-短横模式为固
- Win11蓝牙开关不见了怎么办_Win11蓝牙驱动
- 如何在Golang中指定模块版本_使用go.mod
- c++中的Tag Dispatching是什么_c
- Win11怎么更改系统语言_Win11中文语言包下
- Win11怎么设置闹钟_Windows 11时钟应
- Win11怎么设置默认浏览器Chrome_Wind
- Python类装饰器使用_元编程解析【教程】
- Windows7如何安装系统镜像_Windows7
- Win11怎么开启游戏模式_Win11优化游戏帧数
- c++如何利用doxygen生成开发文档_c++
- c++ unordered_map怎么用 c++哈
- c++怎么使用std::unique实现去重_c+
- 如何用正则与预处理高效拦截带干扰符的恶意域名
- Win11如何设置开机问候语 Win11修改登录界
- 如何使用Golang指针与接口结合_实现方法调用和
- Windows10如何删除Windows.old_
- c++获取当前时间戳_c++ time函数使用详解
- Windows10无法识别USB设备描述符请求失败
- php嵌入式多设备通信怎么实现_php同时管理多个
- Win11如何设置省电模式 Win11开启电池节电
- 如何使用Golang实现错误包装与传递_Golan
- Laravel 查询 JSON 列:高效筛选包含数
- 如何在Golang中实现服务熔断与限流_Golan
- Win11输入法切换快捷键怎么改_Windows
- Go语言中slice追加操作的底层共享机制详解
- 如何在网页无标准表格标签时高效提取结构化数据
- php怎么下载安装后无法解析php文件_服务器配置
- 如何在Golang中定义接口_抽象方法和多态实现
- Win10怎么限制单程序CPU占用上限_Win10
- Python路径拼接规范_跨平台处理说明【指导】
- Mac怎么给文件夹加密_Mac创建加密磁盘映像教程
- Windows系统被恶意软件破坏后的恢复策略_错误
- Go 语言标准库为何不提供泛型切片的 Contai
- Win11屏幕亮度突然变暗怎么解决_自动变暗问题处
- 如何在Golang中验证模块完整性_Golangg
- VSC怎样在VSC中调试PHPAPI_接口调试技巧
- Python变量绑定机制_引用模型解析【教程】
- c++如何实现一个高性能的环形队列(Ring Bu
- Win11如何暂停系统更新 Win11暂停更新最长
- PHP主流架构怎么监控运行状态_工具推荐【操作】
- Win10如何更改电脑休眠时间_Windows10
- 如何使用Golang实现容器健康检查_监控和自动重
- mac怎么安装pip_MAC Python pip
- 如何在 PHP 单元测试中正确模拟带方法的图像处理
- c++怎么用jemalloc c++替换默认内存分
- Win11局域网共享怎么设置 Win11文件夹网络
- Win10怎样设置多显示器_Win10多显示器扩展


QQ客服