如何为继承父类验证器的attrs子类设置属性默认值?
attrs子类设置父类字段默认值并保留验证器的正确方式
首先看给定的父类定义:
from attrs import define, field, validators @define(kw_only=True) class Vehicle: num_wheels: int = field(validator=validators.instance_of(int)) @num_wheels.validator def validate_num_wheels(self, attribute, value) -> None: if value <= 0: raise ValueError("Number of wheels must be greater than 0")
需求很明确:创建Car、Motorbike这类子类,给num_wheels设置专属默认值(比如Car默认4轮,Motorbike默认2轮),同时要保留父类的验证逻辑——既不能让非法值(比如负数、非整数)通过初始化,又要支持无参调用Car()或Motorbike()自动使用默认值。
你提到的手动实现__init__调用__attrs_init__的方案是可行的:
@define class Car(Vehicle): def __init__(self, *, num_wheels: int = 4, **kwargs): self.__attrs_init__(num_wheels=num_wheels, **kwargs)
这个写法能正常触发父类的所有验证器,因为__attrs_init__是attrs自动生成的初始化方法,会完整执行父类定义的字段校验逻辑。但这种写法不够简洁,attrs本身提供了更优雅的实现方式。
更合适的实现方式
直接在子类中重新声明num_wheels字段,指定默认值的同时复用父类的验证器:
@define(kw_only=True) class Car(Vehicle): num_wheels: int = field( default=4, validator=Vehicle.num_wheels.validator ) @define(kw_only=True) class Motorbike(Vehicle): num_wheels: int = field( default=2, validator=Vehicle.num_wheels.validator )
这样写既保留了父类的双重验证(类型检查+正整数校验),又给子类设置了专属默认值,而且完全符合attrs的语法规范。
如果觉得每次引用Vehicle.num_wheels.validator有点繁琐,还可以把父类的验证器抽成独立函数,这样子类直接复用更方便:
from attrs import define, field, validators def validate_positive_int(attribute, value) -> None: if not isinstance(value, int): raise TypeError(f"{attribute.name} must be an integer") if value <= 0: raise ValueError(f"{attribute.name} must be greater than 0") @define(kw_only=True) class Vehicle: num_wheels: int = field(validator=validate_positive_int) @define(kw_only=True) class Car(Vehicle): num_wheels: int = field(default=4, validator=validate_positive_int) @define(kw_only=True) class Motorbike(Vehicle): num_wheels: int = field(default=2, validator=validate_positive_int)
这种方式进一步解耦了验证逻辑,代码复用性更强,后续如果要修改验证规则,只需要修改validate_positive_int一个函数即可。
验证效果测试
不管用哪种方式,以下测试场景都能符合预期:
Car():正常初始化,num_wheels为4Motorbike(num_wheels=3):正常初始化Car(num_wheels=-1):抛出ValueErrorCar(num_wheels=3.14):抛出TypeError(或ValueError,取决于验证器顺序)
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

