Python中function signature(函数签名)具体指什么?
Python语境下的函数签名(function signature)定义
和C++、Java这类静态语言把函数签名作为编译器判断重载依据、仅包含函数名+参数类型列表的定义不同,Python语境下的函数签名是可调用对象(普通函数、类、实现了__call__的实例、偏函数等都算)调用规则的结构化元数据,你可以通过标准库inspect.signature()直接获取任意可调用对象的签名实例。
它的核心组成部分只有三类:
- 全量形参元信息:会记录每个参数的名称、参数类别(仅位置参数、普通位置/关键字参数、仅关键字参数、可变位置参数
*args、可变关键字参数**kwargs)、是否配置默认值、默认值的具体内容、参数绑定的类型注解。比如定义def demo(a: int, b: str = "t", *args, c: bool, **kwargs),签名会完整记录所有5类参数的属性,不会因为Python是动态类型就省略参数名、参数分类这类信息。 - 返回值注解:如果函数定义时写了
-> xxx形式的返回值标注,这部分内容会存在签名的return_annotation属性中,未标注时该属性值为特殊标记inspect.Signature.empty。注意签名不会记录函数运行时实际的返回值类型——毕竟动态语言的返回值类型只有执行时才能确定。 - 适配后的调用规则:经过
functools.partial包装的偏函数,签名会自动剔除已经被固定的参数,和实际调用时需要传入的参数列表完全匹配;类对象的签名会自动对齐__init__方法的参数规则,可调用实例的签名会对齐自身__call__方法的规则。
要注意一个常见误区:Python的函数签名不包含函数名。函数名只是指向函数对象的变量标识符,不属于调用规则的一部分,自然不算签名内容。另外Python本身不支持靠参数类型/个数差异实现的静态重载,所以签名也不是给编译器做重载匹配用的,它的实际用途集中在框架参数解析(比如FastAPI的请求参数绑定、Click的命令行参数生成)、装饰器参数透传、文档自动生成、入参合法性校验这类场景。
你可以用这段简单的代码直观感受签名的内容:
import inspect def greet(name: str, greeting: str = "Hello") -> str: return f"{greeting}, {name}!" func_sig = inspect.signature(greet) print(func_sig) # 控制台输出: (name: str, greeting: str = 'Hello') -> str
内容的提问来源于stack exchange,提问作者Hajin Lee
相关产品推荐
相关产品推荐

