我希望使用attrs与Node
个孩子一起编写一个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))
如何获得我想要的行为?
谢谢!
答案 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 = ...
由于某些节点不可避免地必须离开,因此您还必须允许left
和right
为NoneType
。最后,提供默认值意味着您可以将节点初始化为Node()
,而不是Node(None, None)
。例如,
>>> tree = Node(right=Node(Node()))
>>> tree
Node(left=None, right=Node(left=Node(left=None, right=None), right=None))