假设我得到了以下一段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),但在我的情况下,它不仅仅是一个列表,而且还有一个树形结构,我无法使这个组合起作用。
答案 0 :(得分:0)
如果您需要在要启动的林类中执行操作,您也可以在add_child中调用它。因此,如果需要更新顶点,只需在每次调用add_child时更新它们。您还需要通过将节点传递到默认构造函数来跟踪节点所在的林。
def add_child(self, node):
node._parent = self
self._children.append(node)
self._forest.on_add_child(node)