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

Python中快速将构造参数转为类变量的更简洁实现方案求助

需求说明

初始化类实例时,将__init__方法接收的全部位置参数、关键字参数自动设置为所属类的类变量。

现有实现版本

初始版本

class Example():
    def __init__(
        self,
        a: str,
        b: bool,
        c: int,
        d="str",
        e=True,
        f=123,
    ):
        class_member = dict(locals())
        del class_member["self"]
        self.set_property(class_member)

    @classmethod
    def set_property(cls, kwargs):
        for key, value in kwargs.items():
            setattr(cls, key, value)

a = Example("test", True, 1, d="test", e=False, f=456)
print(Example.d)  # test

自行简化版本

class Example():
    def __init__(
        self,
        a: str,
        b: bool,
        c: int,
        d="str",
        e=True,
        f=123,
    ):
        class_member = dict(locals())
        del class_member["self"]
        for key, value in class_member.items():
            setattr(Example, key, value)

a = Example("test", True, 1, d="test", e=False, f=456)
print(Example.d)  # test
更简洁的实现方案
  • 方案1:单类极简版本(无需额外导包,比现有简化版少一行代码)
    直接遍历locals()跳过self即可,不需要额外做删除操作:
class Example():
    def __init__(self, a: str, b: bool, c: int, d="str", e=True, f=123):
        for k, v in locals().items():
            if k != "self":
                setattr(Example, k, v)

a = Example("test", True, 1, d="test", e=False, f=456)
print(Example.d)  # 输出 test
  • 方案2:通用装饰器版本(适合多类复用,稳定性更高)
    用装饰器封装参数提取、赋值的通用逻辑,同时用inspect提取参数避免locals()误把__init__内的临时变量识别为入参的问题:
from functools import wraps
import inspect

def auto_set_class_vars(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        func(self, *args, **kwargs)
        sig = inspect.signature(func)
        # 提取参数(跳过self)
        param_list = list(sig.parameters.keys())[1:]
        # 合并位置、关键字参数
        all_args = dict(zip(param_list, args))
        all_args.update(kwargs)
        # 填充未传参的默认值
        for name, param in sig.parameters.items():
            if name == "self" or name in all_args:
                continue
            if param.default is not inspect.Parameter.empty:
                all_args[name] = param.default
        # 批量赋值类变量
        for k, v in all_args.items():
            setattr(type(self), k, v)
    return wrapper

# 使用时只需加装饰器,无需写重复的参数处理逻辑
class Example():
    @auto_set_class_vars
    def __init__(self, a: str, b: bool, c: int, d="str", e=True, f=123):
        # 可自由写其他初始化逻辑
        pass

a = Example("test", True, 1, d="test", e=False, f=456)
print(Example.d)  # 输出 test
注意事项
  • 现有逻辑每次创建实例都会覆盖类的同名属性,若创建多个实例,最后一个实例的入参会成为最终的类变量值,若只需首次初始化赋值需要额外加状态判断。
  • 用locals()的方案要注意不要在变量遍历前定义__init__内部的临时变量,否则临时变量也会被误设为类变量,对稳定性要求高推荐用inspect方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:45:06