如何获取Python构造函数调用时传入的显式命名参数?
解决Python类实例捕获显式传入构造函数参数的问题
问题场景
给定如下代码片段:
class A: def __init__(self, p1=1, p2=None, p3="test"): self.p1 = p1 self.p2 = p2 self.p3 = p3 a1 = A() a2 = A(p1=2, p3="blah")
需要实现:
a1实例返回{}(无显式传入参数)a2实例返回{"p1": 2, "p3": "blah"}(仅保留显式传入的命名参数)
之前尝试inspect模块和locals()均无法满足需求——locals()会包含默认值填充的参数,单独用inspect无法区分调用时的显式传入项。
可行解决方案:用装饰器捕获显式参数
通过装饰器包装构造函数,结合inspect模块的参数签名功能,精准捕获调用时显式传入的参数:
import inspect def track_explicit_args(func): # 获取构造函数的参数签名 sig = inspect.signature(func) def wrapper(self, *args, **kwargs): # 收集所有显式传入的参数:位置参数+关键字参数 explicit_args = {} # 处理位置参数:按参数顺序映射到对应名称 param_names = [name for name in sig.parameters if name != 'self'] for idx, val in enumerate(args): explicit_args[param_names[idx]] = val # 处理关键字参数 explicit_args.update(kwargs) # 将显式参数存储到实例属性中 self._explicit_args = explicit_args # 执行原构造函数逻辑 return func(self, *args, **kwargs) return wrapper class A: @track_explicit_args def __init__(self, p1=1, p2=None, p3="test"): self.p1 = p1 self.p2 = p2 self.p3 = p3 # 测试验证 a1 = A() print(a1._explicit_args) # 输出:{} a2 = A(p1=2, p3="blah") print(a2._explicit_args) # 输出:{'p1': 2, 'p3': 'blah'} a3 = A(3, p2="custom") print(a3._explicit_args) # 输出:{'p1': 3, 'p2': 'custom'}
方案原理
- 装饰器通过
inspect.signature获取构造函数的参数定义,明确参数名称和顺序。 - 调用构造函数时,直接收集传入的位置参数和关键字参数——这些就是用户显式传入的内容,完全不涉及默认值填充的参数。
- 将收集到的参数存储到实例的
_explicit_args属性中,供后续调用使用。
这种方法既不污染原构造函数的业务逻辑,又能精准区分显式传入参数和默认参数,完全满足需求。
内容的提问来源于stack exchange,提问作者Aden Dong
相关产品推荐
相关产品推荐

