You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取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'}

方案原理

  1. 装饰器通过inspect.signature获取构造函数的参数定义,明确参数名称和顺序。
  2. 调用构造函数时,直接收集传入的位置参数和关键字参数——这些就是用户显式传入的内容,完全不涉及默认值填充的参数。
  3. 将收集到的参数存储到实例的_explicit_args属性中,供后续调用使用。

这种方法既不污染原构造函数的业务逻辑,又能精准区分显式传入参数和默认参数,完全满足需求。

内容的提问来源于stack exchange,提问作者Aden Dong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:45:32