怎样利用Python的Inspect模块在运行时获取函数的参数结构?

云丽同学_6203

云丽同学_6203

2026-07-16

1001人浏览

原创

inspect.signature() 返回signature对象,包含参数名、类型注解、默认值、可变参数标识、参数顺序及声明位置等结构化信息,需通过.parameters访问parameter实例获取具体字段。

怎样利用python的inspect模块在运行时获取函数的参数结构?

inspect.signature() 能拿到什么信息?

inspect.signature() 返回的是 Signature 对象,不是字符串也不是字典,而是一个结构化描述——它包含所有参数名、类型注解、默认值、是否可变参数(*args / **kwargs)、参数顺序,甚至参数的声明位置(比如是位置参数还是仅关键字参数)。

常见错误是直接 print 它,结果看到一长串类似 <signature int b="1,"></signature> 的输出,误以为“拿到了”,其实这只是 repr;真正要用字段,得手动访问 .parameters。

  • .parameters 是一个 OrderedDict,key 是参数名,value 是 Parameter 实例
  • 每个 Parameter 有 .name、.default(没默认值时为 inspect.Parameter.empty)、.annotation(类型注解,也可能为 inspect.Parameter.empty)、.kind(如 Parameter.POSITIONAL_ONLY、Parameter.KEYWORD_ONLY 等)
  • 注意:函数没写类型注解时,.annotation 就是 inspect.Parameter.empty,别拿它当 None 判断
import inspect
<p>def example(a: int, b=1, *args, c: str = "hello", **kwargs):
pass</p><p>sig = inspect.signature(example)
for name, param in sig.parameters.items():
print(f"{name}: kind={param.kind}, default={param.default}, annotation={param.annotation}")</p>

如何安全提取参数名和默认值?

不能直接用 param.default 做逻辑判断,因为显式设为 None 和没设默认值都返回 inspect.Parameter.empty,但语义完全不同。

Python Use Agent
Python Use Agent

智能执行Python任务,自动生成、执行代码并反馈结果,无需额外配置,兼容旧命令。

下载
  • 用 param.default is inspect.Parameter.empty 判断是否“无默认值”
  • 用 param.annotation is not inspect.Parameter.empty 判断是否有类型注解
  • 如果要构建调用参数字典(比如做 mock 或自动填充),只取 kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY) 的参数,跳过 *args 和 **kwargs(它们没有独立名字)
def get_keyword_defaults(func):
    sig = inspect.signature(func)
    defaults = {}
    for param in sig.parameters.values():
        if param.kind in (inspect.Parameter.POSITIONAL_OR_KEYWORD, inspect.Parameter.KEYWORD_ONLY):
            if param.default is not inspect.Parameter.empty:
                defaults[param.name] = param.default
    return defaults

为什么 inspect.getfullargspec() 有时会失效?

inspect.getfullargspec() 是旧接口,对带装饰器的函数经常失效——它不穿透装饰器,返回的可能是包装函数的参数,而不是原始函数的。而 inspect.signature() 默认会尝试用 <strong>wrapped</strong> 向下找,但前提是装饰器正确设置了该属性(比如用 @functools.wraps)。

  • 没用 @functools.wraps 的自定义装饰器,signature() 也会卡在 wrapper 层
  • getfullargspec() 还不支持 typing.Literal、typing.Union 等新注解,解析出来是 typing.Union 类型对象,不是字符串
  • 遇到 TypeError: unsupported callable,大概率是传了 built-in 函数(如 len、print),它们没有 Python 层源码,signature() 只能靠 heuristics 推测,有时失败

实际用在装饰器里要注意什么?

想写一个“自动记录调用参数”的装饰器,不能只靠 signature() 抓定义,还得结合 *args、**kwargs 运行时传入的值做绑定。

  • 用 sig.bind(*args, **kwargs) 得到 BoundArguments,再调 .apply_defaults() 才能补全所有默认值
  • bind() 会校验参数合法性,如果传参错,它直接抛 TypeError,不是静默忽略
  • 不要直接修改 BoundArguments.arguments 字典(它是浅拷贝),真要改用 .arguments.copy()
def log_call(func):
    sig = inspect.signature(func)
    def wrapper(*args, **kwargs):
        bound = sig.bind(*args, **kwargs)
        bound.apply_defaults()
        print("called with:", bound.arguments)
        return func(*args, **kwargs)
    return wrapper

参数绑定这一步绕不开,光看 signature 不等于知道这次调用具体传了什么。很多动态分析工具卡在这里——以为拿到 signature 就万事大吉,结果漏掉了实参映射逻辑。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1651

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4084

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1649

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

23577

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2887

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2927

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1143

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2263

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程