能否获取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
相关产品推荐
相关产品推荐

