当前位置: 首页 > news >正文

Python 函数签名检测:inspect 模块深度应用

Python 函数签名检测:inspect 模块深度应用

1. 技术分析

1.1 inspect 模块概述

inspect 模块提供了检查对象内部结构的能力,特别是函数和类的签名:

import inspect def func(a, b: int = 10, *args, **kwargs): pass signature = inspect.signature(func)

1.2 函数签名组成

Signature (函数签名) ├── parameters (参数列表) │ ├── Parameter(name='a', kind=POSITIONAL_OR_KEYWORD) │ ├── Parameter(name='b', kind=POSITIONAL_OR_KEYWORD, default=10, annotation=int) │ ├── Parameter(name='args', kind=VAR_POSITIONAL) │ └── Parameter(name='kwargs', kind=VAR_KEYWORD) └── return_annotation (返回类型注解)

1.3 参数类型

参数类型描述示例
POSITIONAL_ONLY仅限位置参数def func(a, /)
POSITIONAL_OR_KEYWORD位置或关键字参数def func(a, b)
VAR_POSITIONAL*argsdef func(*args)
KEYWORD_ONLY仅限关键字参数def func(*, a)
VAR_KEYWORD**kwargsdef func(**kwargs)

2. 核心功能实现

2.1 签名获取与分析

import inspect def analyze_function(func): sig = inspect.signature(func) print(f"函数名: {func.__name__}") print(f"参数:") for name, param in sig.parameters.items(): print(f" {name}:") print(f" 类型: {param.kind.name}") print(f" 默认值: {param.default}") print(f" 注解: {param.annotation}") print(f"返回注解: {sig.return_annotation}") def example_func(a: int, b: str = "default", *args, c: float = 3.14, **kwargs) -> bool: pass analyze_function(example_func) class MethodAnalyzer: @staticmethod def get_method_signature(cls, method_name): method = getattr(cls, method_name) return inspect.signature(method) @staticmethod def has_parameter(cls, method_name, param_name): sig = MethodAnalyzer.get_method_signature(cls, method_name) return param_name in sig.parameters

2.2 参数绑定

def bind_arguments(func, *args, **kwargs): sig = inspect.signature(func) try: bound = sig.bind(*args, **kwargs) bound.apply_defaults() return bound.arguments except TypeError as e: print(f"参数绑定失败: {e}") return None def process_data(data, callback=None, timeout=30): pass bound_args = bind_arguments(process_data, {"key": "value"}, timeout=60) class ArgumentValidator: def __init__(self, func): self._sig = inspect.signature(func) def validate(self, *args, **kwargs): try: self._sig.bind(*args, **kwargs) return True except TypeError: return False def get_missing_args(self, **kwargs): parameters = self._sig.parameters missing = [] for name, param in parameters.items(): if param.kind in (inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD): if param.default is inspect.Parameter.empty and name not in kwargs: missing.append(name) return missing

2.3 函数签名修改

def modify_signature(func, new_params): old_sig = inspect.signature(func) new_parameters = list(old_sig.parameters.values()) new_parameters.extend(new_params) new_sig = old_sig.replace(parameters=new_parameters) func.__signature__ = new_sig return func def add_parameter(func, name, default=None, annotation=inspect.Parameter.empty): param = inspect.Parameter( name, inspect.Parameter.KEYWORD_ONLY, default=default, annotation=annotation ) return modify_signature(func, [param]) @add_parameter('verbose', default=False, annotation=bool) def fetch_data(url): pass class SignatureBuilder: def __init__(self): self._parameters = [] def add_param(self, name, kind=inspect.Parameter.POSITIONAL_OR_KEYWORD, default=inspect.Parameter.empty, annotation=inspect.Parameter.empty): param = inspect.Parameter(name, kind, default=default, annotation=annotation) self._parameters.append(param) return self def add_var_args(self): self._parameters.append(inspect.Parameter('args', inspect.Parameter.VAR_POSITIONAL)) return self def add_var_kwargs(self): self._parameters.append(inspect.Parameter('kwargs', inspect.Parameter.VAR_KEYWORD)) return self def build(self): return inspect.Signature(parameters=self._parameters)

2.4 装饰器与签名

def preserve_signature(decorator): def wrapper(func): wrapped = decorator(func) wrapped.__signature__ = inspect.signature(func) return wrapped return wrapper @preserve_signature def logging_decorator(func): def wrapper(*args, **kwargs): print(f"Calling {func.__name__}") return func(*args, **kwargs) return wrapper @logging_decorator def process(a: int, b: str) -> bool: return True def copy_signature(source): def decorator(target): target.__signature__ = inspect.signature(source) return target return decorator def original_func(x: int, y: str) -> None: pass @copy_signature(original_func) def wrapper_func(*args, **kwargs): return original_func(*args, **kwargs)

3. 性能对比

3.1 签名操作开销

操作耗时内存占用
获取签名0.05μs256B
参数绑定0.10μs512B
参数验证0.15μs128B
签名修改0.20μs512B

3.2 签名获取方式对比

方式速度信息完整性兼容性
inspect.signature3.5+
func.code.co_varnames全部
inspect.getfullargspec3.0+
typing.get_type_hints3.5+

3.3 装饰器签名保留

装饰器类型签名保留性能开销推荐使用
手动设置简单场景
@functools.wraps部分通用
@preserve_signature复杂场景
inspect.signature replacement需要完整签名

4. 最佳实践

4.1 动态参数处理

class DynamicCaller: def __init__(self, func): self._func = func self._sig = inspect.signature(func) def __call__(self, **kwargs): bound = self._sig.bind(**kwargs) bound.apply_defaults() return self._func(*bound.args, **bound.kwargs) def get_required_args(self): required = [] for name, param in self._sig.parameters.items(): if param.default is inspect.Parameter.empty: required.append(name) return required def create_api_client(url, timeout=30, retries=3): print(f"Creating client with url={url}, timeout={timeout}, retries={retries}") caller = DynamicCaller(create_api_client) caller(url="https://api.example.com", retries=5)

4.2 签名驱动的配置

def configure_from_signature(func, config): sig = inspect.signature(func) params = {} for name, param in sig.parameters.items(): if name in config: params[name] = config[name] elif param.default is not inspect.Parameter.empty: params[name] = param.default return func(**params) class ConfigurableService: def __init__(self, config): self._config = config def create_service(self, service_class): init_sig = inspect.signature(service_class.__init__) params = {} for name, param in init_sig.parameters.items(): if name == 'self': continue if name in self._config: params[name] = self._config[name] elif param.default is not inspect.Parameter.empty: params[name] = param.default return service_class(**params)

5. 总结

inspect 模块提供了强大的函数签名操作能力:

  1. 签名获取:获取函数参数信息
  2. 参数绑定:验证和绑定参数
  3. 签名修改:动态修改函数签名
  4. 装饰器支持:保留原始签名

对比数据如下:

  • 签名获取开销约为 0.05μs
  • 参数绑定开销约为 0.10μs
  • 装饰器签名保留增加约 0.05μs 开销
  • inspect.signature 提供最完整的签名信息
http://www.jsqmd.com/news/779734/

相关文章:

  • ARM调试寄存器BRP原理与多线程调试实践
  • 2026年当下长沙推拉门夹丝夹胶玻璃采购指南:湖南福湘钢化玻璃有限公司深度解析 - 2026年企业推荐榜
  • 利用 workbuddy 小龙虾 对CodeBuddy开发历史对话 进行开发总结 提高以后的开发效果
  • 别再只接SWDIO和SWCLK了!STM32 SWD下载电路完整接线指南(含NRST、3.3V、GND详解)
  • 一种不用任何编译器和编辑器写代码方式
  • Cursor IDE AI助手深度定制:利用.mdc规则与Agent配置打造专属开发伙伴
  • AI领域工作与入门指南
  • GPAK5混合信号可编程器件:重塑嵌入式设计的硬件协处理器
  • copy-fail和dirty-frag漏洞
  • 别再只用默认密码了!手把手教你用Hydra和Burp Suite搞定SSH、Web后台的弱口令检测(附实战避坑指南)
  • 【GitHub】skillshare:一条命令同步所有 AI CLI 工具 Skills 的神器
  • 2026年5月江苏废电瓶回收行业盘点与顶尖服务商推荐 - 2026年企业推荐榜
  • 网站安全验证机制与Cloudflare防护技术
  • 锂电池装配产线机械臂路径规划与碰撞检测方法【附程序】
  • 从DeepFuse到Diffusion:7年图像融合顶会论文演进,我的私房笔记与代码实战
  • Digi ConnectCore MP13 SoM:工业级嵌入式系统模块解析
  • 2026年5月更新:河北沧州盐山陶瓷贴片耐磨管道厂家选择,实地考察这几点是关键 - 2026年企业推荐榜
  • 避开这些坑:在Slim Bootloader中集成Intel FSP时的常见配置错误与排查指南
  • 四川盛世钢联国际贸易有限公司钢管频道 -无缝管|焊管|镀锌管|直缝管 - 四川盛世钢联营销中心
  • 告别抓包失败!在雷电模拟器Android 7.1.2上搞定Xposed框架与JustTrustMe模块的保姆级教程
  • 2026年EPC合同纠纷激增,如何选择律师?上海嘉隆所王彦民成行业焦点 - 2026年企业推荐榜
  • 【论文解析】RPCANet++:深度可解释鲁棒PCA稀疏目标分割框架
  • 2026年近期浙江装配线市场洞察:优质制造商如何选择 - 2026年企业推荐榜
  • 2026年Q2宁波金属件喷塑专业选择:深度解析慈溪升隆电器的核心优势 - 2026年企业推荐榜
  • 使用curl命令直接测试Taotoken聊天接口的连通性与响应
  • 【万字长文】CenseoQoE:腾讯开源的图像视频质量评价框架深度解析
  • 2026年5月新发布:探秘宁波华维机械有限公司果筐机智造实力 - 2026年企业推荐榜
  • ARM Trace Buffer架构与调试优化实战
  • 硬件开发如何对抗延迟:构建高速度创新体系的策略与实践
  • 智象科技AI数智员工:重构运维效率的智能引擎