在attrs中,验证属性类型是封闭类

时间:2017-10-11 16:34:20

标签: python python-3.x tree

我希望使用attrsNode个孩子一起编写一个Node个课程,并进行验证。

以下不会编译,因为Node尚不存在 -

from attr import attrs, attrib
from attr.validators import instance_of

@attrs
class Node:
    left = attrib(validator=instance_of(Node))
    right = attrib(validator=instance_of(Node))

如何获得我想要的行为?

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以创建一个虚拟Node类(调用此对象A),以便它是一个注册名称以避免NameError,然后您可以创建您的普通类,确保继承自虚拟的(称为此对象B)。

from attr import attrs, attrib
from attr.validators import instance_of

class Node:
    pass

@attrs
class Node(Node):
    left = attrib(default=None, validator=instance_of((Node, type(None))))
    right = attrib(default=None, validator=instance_of((Node, type(None))))

从技术上讲,对象A的名称已被覆盖,但仍保留对它的引用。因此,当您调用Node()时,您实际上正在处理对象B.这是对象A和对象B类型,但在instance_of()中检查的类型是严格对象A这对我们来说很好,但解释了为什么继承很重要。

class Node:
    pass

# This won't work because every `Node` we initialise will be strictly object B,
# but the validator requires a type of object A
@attrs
class Node:
    left = ...

由于某些节点不可避免地必须离开,因此您还必须允许leftrightNoneType。最后,提供默认值意味着您可以将节点初始化为Node(),而不是Node(None, None)。例如,

>>> tree = Node(right=Node(Node()))
>>> tree
Node(left=None, right=Node(left=Node(left=None, right=None), right=None))