inspect.signature() 是获取函数签名的首选方法,返回 signature 对象,支持 args、*kwargs、默认值、类型注解和 keyword-only 参数;需传函数对象而非调用结果,适用于普通函数、lambda、内置函数(部分)及 __init__;无签名时抛 valueerror;python 3.5+ 支持;解析时重点看 parameters ordereddict 中每个 parameter 的 name、default、annotation 和 kind 字段;bind() 可安全校验并绑定参数,apply_defaults() 补全默认值;装饰器须用 @functools.wraps 保证签名穿透;partial 对象签名亦被正确识别。

inspect.signature() 是获取函数签名的首选方法
直接用 inspect.signature(),它返回一个 Signature 对象,比已弃用的 inspect.getargspec() 更可靠,能正确处理 *args、**kwargs、默认值、类型注解和 keyword-only 参数。
常见错误是传入函数调用结果(比如 inspect.signature(func())),实际应传函数对象本身:inspect.signature(func)。
- 对普通函数、lambda、内置函数(部分支持)、类的
__init__都适用 - 若函数无签名(如某些 C 扩展函数),会抛出
ValueError: callable <...> is not a function</...>或ValueError: no signature found - Python 3.5+ 支持,无需额外判断版本
解析 Signature 对象时重点看 parameters 属性
Signature.parameters 是一个 OrderedDict,键为参数名,值为 Parameter 实例。每个 Parameter 包含 name、default、annotation 和 kind 四个关键字段。
容易忽略的是 kind 字段——它决定了参数类型:Parameter.POSITIONAL_ONLY、Parameter.KEYWORD_ONLY、Parameter.VAR_POSITIONAL(即 *args)、Parameter.VAR_KEYWORD(即 **kwargs)等。
-
param.default is Parameter.empty表示该参数无默认值 -
param.annotation is Parameter.empty表示无类型注解,不是None - 不要用
str(sig)做逻辑判断,它只是格式化字符串,丢失结构信息
处理绑定参数时要用 bind() 而非手动匹配
当你要验证某组参数是否合法、或做参数预填充时,用 signature.bind() ——它会按规则检查参数个数、位置、关键字匹配,并返回 BoundArguments。
典型误操作是自己写 if 判断 *args 长度或遍历 **kwargs 键,既易错又漏掉 keyword-only 约束。
- 调用
sig.bind(1, x=2)成功则返回BoundArguments;失败抛TypeError - 后续可调用
bound.apply_defaults()补全默认值,再通过bound.arguments获取完整字典 - 注意:bind 不接受多余关键字参数,除非函数签名中包含
**kwargs
装饰器里用 inspect.signature 要小心闭包和 wrapper 问题
给函数加装饰器后,原函数的 __name__ 和 __doc__ 可能被覆盖,但 inspect.signature() 默认仍能穿透到原始函数(得益于 @functools.wraps 的实现),前提是装饰器用了 @wraps。
如果没用 @wraps,inspect.signature() 会返回装饰器内部 wrapper 的签名(通常只有 *args, **kwargs),而非被装饰函数的真实签名。
- 检查方式:打印
inspect.signature(decorated_func).parameters,看是否和原函数一致 - 自定义装饰器务必加
@functools.wraps(func),否则签名丢失是静默故障 - 对于
partial对象,inspect.signature()也能正确反映“冻结”后的参数形态
真正麻烦的不是怎么取签名,而是拿到之后怎么安全地映射参数名到实际值——尤其当函数有 kwonly 参数或 positional-only 时,BoundArguments.arguments 的顺序和结构必须严格依赖 signature 解析结果,不能靠字符串匹配或位置硬编码。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











