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

能否获取Python类实例的初始化参数及对应值?

获取Python类实例的初始化参数及对应值

下面给你几种可行的实现方案,根据你使用的类的具体情况选择:

方案一:类已将初始化参数保存为实例属性

如果SomeClass的__init__方法里已经把a、b这类参数赋值给了实例属性(比如self.a = a),可以借助inspect模块来实现需求:

import inspect

def get_init_params_and_values(instance):
    # 获取类的__init__方法签名
    init_sig = inspect.signature(instance.__class__.__init__)
    params = {}
    # 遍历__init__的参数(跳过第一个self参数)
    for param_name in list(init_sig.parameters.keys())[1:]:
        # 只提取目标参数a和b
        if param_name in ['a', 'b']:
            try:
                params[param_name] = getattr(instance, param_name)
            except AttributeError:
                # 实例无该属性则跳过
                pass
    return params

# 测试示例
class SomeClass:
    def __init__(self, a, b, c=30):
        self.a = a
        self.b = b
        self.c = c

blah = SomeClass(a=10, b=20)
print(get_init_params_and_values(blah))  # 输出: {'a': 10, 'b': 20}

方案二:类未保存初始化参数到实例属性

如果SomeClass的__init__没有把参数存为实例属性,就需要提前通过装饰器或元类来记录初始化时传入的参数:

用装饰器实现

import inspect

def track_init_params(cls):
    original_init = cls.__init__
    def new_init(self, *args, **kwargs):
        # 绑定传入的参数到__init__签名,区分位置/关键字参数
        init_sig = inspect.signature(original_init)
        bound_args = init_sig.bind(self, *args, **kwargs)
        bound_args.apply_defaults()
        # 把目标参数存在实例私有属性中
        self._init_params = {k: v for k, v in bound_args.arguments.items() if k in ['a', 'b']}
        original_init(self, *args, **kwargs)
    cls.__init__ = new_init
    return cls

# 测试示例
@track_init_params
class SomeClass:
    def __init__(self, a, b, c=30):
        # 未将a、b赋值为实例属性
        pass

blah = SomeClass(a=10, b=20)
# 封装成目标函数
def get_init_params_and_values(instance):
    return getattr(instance, '_init_params', {})

print(get_init_params_and_values(blah))  # 输出: {'a': 10, 'b': 20}

用元类实现

如果需要给多个类统一添加参数记录功能,元类是更合适的选择:

import inspect

class TrackInitParamsMeta(type):
    def __new__(cls, name, bases, attrs):
        original_init = attrs.get('__init__')
        def new_init(self, *args, **kwargs):
            init_sig = inspect.signature(original_init)
            bound_args = init_sig.bind(self, *args, **kwargs)
            bound_args.apply_defaults()
            self._init_params = {k: v for k, v in bound_args.arguments.items() if k in ['a', 'b']}
            original_init(self, *args, **kwargs)
        attrs['__init__'] = new_init
        return super().__new__(cls, name, bases, attrs)

# 测试示例
class SomeClass(metaclass=TrackInitParamsMeta):
    def __init__(self, a, b, c=30):
        pass

blah = SomeClass(a=10, b=20)
print(get_init_params_and_values(blah))  # 输出: {'a': 10, 'b': 20}

注意事项

  • 不管是位置参数(如blah = SomeClass(10,20))还是关键字参数,上述方案都能正确识别对应关系;
  • 若需要提取的参数不止a和b,修改代码中的参数列表即可;
  • 方案二中的_init_params是私有属性,避免和类自身的属性冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:07:33