使用Python模块,我试图让一个子类的属性比其父类更具限制性,就像下面的最小例子一样。
break
定义上述验证器会引发错误(import attr
@attr.s
class Base:
x = attr.ib()
y = attr.ib()
@attr.s
class Child(Base):
@x.validator
def _x_validator(self, a, x):
if x < 0:
raise ValueError()
)。
我通过在子类中重新定义NameError: name 'x' is not defined
找到了解决方法。
x
然而,它会弄乱属性的排序。
@attr.s
class Child(Base):
x = attr.ib()
@x.validator
def _x_validator(self, a, x):
if x < 0:
raise ValueError()
所以,最后,我最终重新定义了子类中的所有属性(实际代码中有两个以上)。
有更优雅的方法吗?
答案 0 :(得分:0)
最后,我发现最简单的解决方法就是不在子类中使用验证器:
@attr.s
class Child(Base):
def __attrs_post_init__(self):
assert self.x > 0
感谢bruno desthuilliers正确地指出Liskov原则。
请注意,问题不仅发生在@x.validator
上,也发生在其他结构上,例如属性默认值@x.default
。在这种情况下,似乎即将发布{3.7} {3}} dataclass
而不是attrs
。