将子项添加到树时的触发方法

时间:2017-07-10 19:24:09

标签: python python-3.x properties tree

假设我得到了以下一段python代码来创建一个包含一堆树的森林。

NEXT_INDEX = 0

class Node:
""" A node of a tree """

    def __init__(self):
        # Each node gets a unique id
        self._index = NEXT_INDEX
        NEXT_INDEX += 1
        # any node may have an arbitrary number of children
        self._children = list()
        self._parent = None

    def add_child(self, node):
        node._parent = self
        self._children.append(node)

    def __str__(self):
        return "node {}".format(self._index)


class Forest:
""" A bunch of trees """

    def __init__(self):
        # contains the root nodes of a whole bunch of trees
        self._trees = list()

    def add_node(self, node):
        # the new node will be the root node for a new tree in self._trees
        self._trees.append(node)

    def find_node(self, idx):
        """
        Search all trees in self._trees for a node with index = idx
        and return that node.
        """
        # Implementation not relevant here
        pass

    def on_add_child(child):
        # should be executed each time add_child is called on a node with the
        # new child as a parameter
        print("on_add_child with child = {}".format(child))

我想执行一个方法" on_add_child",每次将一个孩子添加到任何 任何节点中的任何节点Forest._trees。

重要:print语句必须位于Forest类中。在实际代码中,Forest维护节点的搜索索引,每当添加新的子节点时,必须将新节点添加到搜索索引中。遗憾的是,添加对Forest到节点的引用(以便Node.add_child可以调用Forest.on_add_child)也不是一个选项,因为它会在Node和Forest之间引入循环依赖。

示例:假设我执行了以下代码

forest = Forest()
node_0 = Node()
node_1 = Node()
node_2 = Node()
node_3 = Node()
node_4 = Node()

# We add the first node to the forest: It will become the root of the first tree
forest.add_node(node_0)

# Add node_1 as a child to node_0; This should execute on_add_child(node_1) and
# print "on_add_child with child = node 1"
forest.find_node(0).add_child(node_1)

# Should print "on_add_child with child = node 2"
# => on_add_child is also triggered when we add a child to a non-root node
forest.find_node(1).add_child(node_2)

# Create a second tree
forest.add_node(node_3)

# Should print "on_add_child with child = node 4"
forest.find_node(3).add_child(node_4)

如何实现?我知道python属性,我发现了几个与python列表一起使用属性的相关问题(例如Python property on a list,{{3 }},Python decorating property setter with list),但在我的情况下,它不仅仅是一个列表,而且还有一个树形结构,我无法使这个组合起作用。

1 个答案:

答案 0 :(得分:0)

如果您需要在要启动的林类中执行操作,您也可以在add_child中调用它。因此,如果需要更新顶点,只需在每次调用add_child时更新它们。您还需要通过将节点传递到默认构造函数来跟踪节点所在的林。

def add_child(self, node):
    node._parent = self
    self._children.append(node)
    self._forest.on_add_child(node)