Signature 对象是 Python 的 inspect 模块中用来描述可调用对象(例如函数)的“调用签名”的一种数据结构。换句话说,它是一种结构化的表示形式,告诉你一个函数需要哪些参数、参数的类型、默认值以及函数的返回注解等信息。
主要特点
-
参数信息
Signature 对象内部有一个.parameters
属性,这是一个有序字典(OrderedDict),其中每个键是参数名称,对应的值是一个 Parameter 对象。每个 Parameter 对象记录了单个参数的详细信息,比如:- 参数名
- 类型注解(如果有)
- 默认值(如果没有默认值,则使用特殊标记
Parameter.empty
) - 参数种类(如仅位置参数、位置或关键字参数、可变参数 *args、仅关键字参数、可变关键字参数 **kwargs 等)
-
返回注解
Signature 对象还包含了函数的返回注解。如果函数有返回类型的说明,这部分信息也会保存在 Signature 对象中。 -
方法支持
Signature 对象不仅仅是一个静态的数据存储,还提供了一些有用的方法,比如:bind()
:可以用来将一组实参绑定到参数上,检查调用是否符合函数定义。bind_partial()
:类似于bind()
,但允许部分参数缺失(比如用于构造部分函数)。replace()
:可以创建一个新的 Signature 对象,对某些参数或返回注解进行修改。
举个例子
假设有这样一个函数:
python">def foo(a: int, b: int = 10) -> bool:pass
使用 inspect.signature(foo)
得到的 Signature 对象在打印时会显示为:
(a: int, b: int = 10) -> bool
这个输出告诉我们:
- 函数
foo
接受两个参数,其中a
是必填的(没有默认值),并且类型注解是int
; - 参数
b
有默认值10
,同样注解为int
; - 函数返回的类型注解为
bool
。
如果你进一步访问 inspect.signature(foo).parameters
,你会得到一个有序字典,其中包含参数 a
和 b
的详细信息(每个都是一个 Parameter 对象)。
生活中的比喻
可以把 Signature 对象想象成一道菜的配方说明。配方上写明了这道菜需要哪些原料(参数)、每种原料的用量(默认值)、原料的种类(类型注解)以及这道菜最终会是什么样子(返回注解)。有了这个配方,你就知道如何正确地准备和调配每一种材料,以便做出美味的菜肴。
总之,Signature 对象就是一个全面记录了函数调用规则的说明书,它帮助我们在代码中进行动态分析和参数校验。
示例代码:
def jsonschema1(f):"""Generate a JSON schema for the input parameters of the given function.Parameters:f (FunctionType): The function for which to generate the JSON schema.Returns:Dict: A dictionary containing the function name, description, and parameters schema."""print(inspect.signature(f))print(inspect.signature(f).parameters)jsonschema1(abc)
输出:
inspect.signature(f)
返回的是一个 Signature 对象,它完整地描述了函数 f
的调用签名,包括所有参数以及函数的返回注解。而 inspect.signature(f).parameters
则是这个 Signature 对象的一个属性,它是一个有序字典(OrderedDict),专门存储函数 f
的每个参数的信息,每个键是参数名,对应的值是一个 Parameter 对象,其中包含了该参数的类型注解、默认值、参数种类(如位置参数、关键字参数等)等详细信息。
区别
-
Signature 对象 (
inspect.signature(f)
):- 包含函数的完整签名信息。
- 除了参数信息外,还包括返回注解等其他信息。
- 可以通过打印它来得到类似
(a, b=10, *args, **kwargs) -> return_annotation
的字符串表示。
-
.parameters 属性:
- 是 Signature 对象的一个组成部分。
- 仅包含参数相关的信息,存储为一个有序字典,保证了参数的顺序(与定义时的顺序一致)。
- 每个字典项的值是一个 Parameter 对象,里面详细描述了单个参数的属性(比如类型注解、默认值、参数种类等)。
联系
-
包含关系:
.parameters
是Signature
对象的一个属性。换句话说,当你调用inspect.signature(f)
得到一个 Signature 对象时,其中就包含了一个.parameters
属性,这个属性专门用来存储函数参数的信息。
-
用途互补:
- 如果你只需要查看函数的参数列表及每个参数的详细属性,就可以直接访问
.parameters
。 - 如果你需要了解整个函数的调用签名(包括返回值的注解等信息),则应该使用整个 Signature 对象。
- 如果你只需要查看函数的参数列表及每个参数的详细属性,就可以直接访问
再举个例子
假设有下面这个函数:
python">def foo(a: int, b: int = 10, *args, **kwargs) -> bool:pass
当你调用:
python">sig = inspect.signature(foo)
print(sig) # 输出: (a: int, b: int = 10, *args, **kwargs) -> bool
这个输出就是 Signature 对象提供的完整签名。而当你查看参数信息:
python">params = sig.parameters
print(params)
你可能会看到类似如下的输出(顺序和具体表示可能略有不同):
OrderedDict([('a', <Parameter "a: int">),('b', <Parameter "b: int = 10">),('args', <Parameter "*args">),('kwargs', <Parameter "**kwargs">)
])
这里,每个 Parameter 对象中都包含了参数的详细信息,如类型注解和默认值(如果有)。
总结
- 联系:
.parameters
是Signature
对象的一个属性,二者一起构成了对函数签名的完整描述。 - 区别:
Signature
对象包含整个函数签名(参数及返回注解),而.parameters
只包含参数的详细信息。