2017-10-11 45 views
1

我想編寫一個樹Node類,Node孩子,使用attrs,與驗證。在attrs中,驗證屬性類型是封閉類

以下不編譯,因爲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

不是一個解決方案,但是你不希望能夠將屬性設置爲None嗎? – user2357112

回答

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))