inspect.signature() 是获取函数参数信息的首选方法,能完整提取参数名、类型注解、默认值及可变参数,支持普通函数、lambda和正确装饰的函数,但需注意装饰器穿透、内置函数限制等兼容性问题。

inspect.signature() 是获取参数信息的首选方法
Python 3.5+ 中,inspect.signature() 已取代过时的 inspect.getargspec(),能完整、统一地提取函数签名,包括参数名、类型注解、默认值、可变参数(*args、**kwargs)等。它对普通函数、lambda、带装饰器的函数(需用 functools.wraps)都有效。
常见错误是直接调 inspect.getfullargspec(func) —— 它不支持类型注解,且对某些装饰器包装后的函数会报 ValueError: callables not supported。
- 始终优先用
inspect.signature(func),返回Signature对象 - 通过
.parameters属性遍历所有参数,每个是Parameter实例 - 参数的默认值通过
param.default获取;若为inspect.Parameter.empty,表示无默认值 - 参数类型注解在
param.annotation中,同样可能为inspect.Parameter.empty
如何安全提取参数名和默认值列表
想快速拿到形如 [('x', 1), ('y', inspect.Parameter.empty), ('z', 'default')] 这样的键值对?别手动拼 dict(),注意 Signature 的 parameters 是有序字典(OrderedDict),但遍历时要过滤掉 *args 和 **kwargs 等特殊参数类型。
容易踩的坑:把 Parameter.VAR_POSITIONAL(即 *args)或 Parameter.VAR_KEYWORD(即 **kwargs)也当作普通参数处理,导致后续逻辑出错。
立即学习“Python免费学习笔记(深入)”;
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 遍历
sig.parameters.values(),用param.kind判断类型 - 只处理
Parameter.POSITIONAL_ONLY、Parameter.POSITIONAL_OR_KEYWORD、Parameter.KEYWORD_ONLY - 用
param.default is inspect.Parameter.empty判断是否有默认值,不要用==或is None - 示例:
sig = inspect.signature(func)<br>params = [<br> (name, param.default if param.default is not inspect.Parameter.empty else None)<br> for name, param in sig.parameters.items()<br> if param.kind in (inspect.Parameter.POSITIONAL_OR_KEYWORD,<br> inspect.Parameter.POSITIONAL_ONLY,<br> inspect.Parameter.KEYWORD_ONLY)<br>]
装饰器函数需要特别处理
如果目标函数被装饰(比如 @lru_cache、自定义装饰器),直接传入 inspect.signature() 可能返回装饰器内部的签名,而非原函数的。这是因为很多装饰器没正确使用 @functools.wraps(func) 保留元数据。
现象:调用 inspect.signature(cached_func) 报 ValueError: no signature found,或返回错误参数名(如 self、_wrapped)。
- 先尝试
inspect.unwrap(func)—— 它会递归解开所有标准装饰器(包括@wraps包装的) - 再对解包后的函数调用
inspect.signature() - 若仍失败(如某些 C 扩展函数、内置函数),捕获
ValueError并降级处理(例如仅靠__code__.co_varnames和__defaults__) - 注意:
inspect.unwrap()不保证 100% 成功,尤其对非标准装饰器或动态生成函数
lambda 函数和内置函数的兼容性差异
inspect.signature() 对 lambda 支持良好,但对部分内置函数(如 len、print)可能返回不完整或空签名,因为它们由 C 实现,不暴露 Python 层的参数结构。
典型表现:inspect.signature(len) 返回 (/) 或抛 ValueError;而 inspect.signature(max) 能正确返回含 *args 和 **kwargs 的签名,但默认值全为 empty。
- 对内置函数,不要假设
default字段有意义;实际调用时默认值由 C 层控制 - lambda 可以正常解析,但注意其参数名是生成的(如
lambda x, y: x+y的参数名就是x、y) - 若需强兼容,建议加 fallback:先试
inspect.signature(),异常时用hasattr(func, '__code__')检查是否为纯 Python 函数再降级
参数顺序、默认值存在性、装饰器穿透、内置函数限制——这四点不确认清楚,inspect 就容易返回意料之外的结果。

















