如何在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,提问作者Чёткая ворона
相关产品推荐
相关产品推荐

