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

如何在attrs模块中自定义类属性,支持动态传参实例化?

实现按需定义类属性的解决方案

你用@attrs.define装饰空类后,生成的__init__方法没有预设参数,所以传入a=1, b=2会触发TypeError。要实现按需添加属性,可以通过以下几种方式:

方案1:自定义__init__接受任意关键字参数

直接在类中定义__init__方法,遍历传入的关键字参数并设置为实例属性:

from attrs import define

@define
class MyClass:
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

调用示例:

obj = MyClass(a=1, b=2)
print(obj.a)  # 输出1
print(obj.b)  # 输出2

方案2:禁用attrs自动生成的__init__

如果不需要attrs自动生成初始化逻辑,可以用init=False参数关闭,再自定义初始化方法:

from attrs import define

@define(init=False)
class MyClass:
    def __init__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

方案3:混合固定属性与动态属性

如果需要同时保留固定属性和动态添加属性的能力,可以结合固定字段和关键字参数:

from attrs import define, field

@define
class MyClass:
    fixed_attr: int = field(default=0)
    
    def __init__(self, fixed_attr=0, **kwargs):
        self.fixed_attr = fixed_attr
        for k, v in kwargs.items():
            setattr(self, k, v)

调用示例:

obj = MyClass(fixed_attr=5, x=10, y=20)
print(obj.fixed_attr)  # 输出5
print(obj.x)  # 输出10

补充:让动态属性出现在repr中

默认情况下,attrs生成的__repr__只会显示预定义的属性。如果需要动态添加的属性也出现在repr里,可以自定义该方法:

from attrs import define

@define(init=False)
class MyClass:
    def __init__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)
    
    def __repr__(self):
        attr_str = ", ".join([f"{key}={value!r}" for key, value in self.__dict__.items()])
        return f"MyClass({attr_str})"

调用示例:

obj = MyClass(a=1, b=2)
print(obj)  # 输出MyClass(a=1, b=2)

内容的提问来源于stack exchange,提问作者Чёткая ворона

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 01:06:30