【问题标题】:Attrs validation checking when an attribute is another attrs object当属性是另一个 attrs 对象时进行属性验证检查
【发布时间】:2021-09-30 03:31:09
【问题描述】:

我有两个 attrs 类,其中一个是另一个的属性。我想确保如果一个特定的值被赋予,另一个特定的值。

我查看了验证器,但认为没有任何东西可以捕捉到这一点。

这是我写的:

@attr.s
class C:
    a = attr.ib(validator=attr.validators.instance_of(str))

@attr.s
class D:
    x = attr.ib(validator=attr.validators.instance_of(str))
    z = attr.ib(validator=attr.validators.instance_of(C))

    def __attrs_post_init__(self):
        if self.x == "a":
            assert self.z.a == "a12"
        elif self.x == "b":
            assert self.z.a == "b12"
        elif self.x == "c":
            assert self.z.a == "c12"


d = D(x="a", z=C("a12"))

我认为这行得通,但我感觉我可能遗漏了一些明显的东西。

【问题讨论】:

  • 如果它们之间存在必需的关系,那么拥有两个属性有什么意义?
  • 我看不出这不起作用的任何原因。 C 对象在调用 D() 之前已完全初始化。

标签: python validation python-attrs


【解决方案1】:

你的方法很好,除了你可能不应该在生产代码中使用assert(当你运行python -O时它们会被优化)。

如果 z 出现在 x 之后,您还可以使用 decorator validator 获取部分初始化的实例作为参数,但我发现您的解决方案更稳健,因为它不依赖于属性定义的顺序。

【讨论】:

  • 谢谢,我没有意识到“x 之后的 z”的顺序很重要,所以我必须阅读 :)
  • 只有在使用装饰器验证器时才重要,因为验证器按照定义属性的顺序运行,并获取迄今已初始化的实例作为self 传递。如果您使用__attrs_post_init__,那么您是安全的;所有属性在运行时都已初始化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多