如何查找特定的Python anytree后代?

0 投票
1 回答
23 浏览
提问于 2025-04-12 14:04

以下是一个用Python构建的anytree示例:

top = Node("top")
a = Node("a", parent=top)
b = Node("b", parent=top)
c = Node("c", parent=a)
d = Node("d", parent=a)
e1 = Node("e", parent=c)
e2 = Node("e", parent=a)
c1 = Node("c", parent=b)
e3 = Node("e", parent=c1)
print(RenderTree(top, style=AsciiStyle()).by_attr())

这个代码生成了这样一棵树:

top
|-- a
|   |-- c
|   |   +-- e
|   |-- d
|   +-- e
+-- b
    +-- c
        +-- e

我想要处理位于top下面的节点a/c/e,前提是这个节点存在。如果这个节点不存在,我希望得到None。

这是我实现的代码,它能达到我想要的效果:

gnode = anytree.search.find(top, lambda node : str(node)=="Node('/top/a/c/e')")
print(f"Exp match, rcv {gnode}")

gnode = anytree.search.find(top, lambda node : str(node)=="Node('/top/a/c/f')")
print(f"Exp None, rcv {gnode}")

上面的代码返回了以下结果:

Exp match, rcv Node('/top/a/c/e')
Exp None, rcv None

虽然这段代码可以正常工作,但我在想,可能有更好的方法来实现这个功能——比如像top.get_descendant("a/c/e")这样,直接访问那个节点,而不是去搜索它。

那么,访问top下面的节点a/c/e(如果不存在就返回None)的正确方法是什么呢?

1 个回答

1

通过阅读文档,看起来你需要的是 anytree.resolver 这个模块:

import sys
import anytree

top = anytree.Node("top")
a = anytree.Node("a", parent=top)
b = anytree.Node("b", parent=top)
c = anytree.Node("c", parent=a)
d = anytree.Node("d", parent=a)
e1 = anytree.Node("e", parent=c)
e2 = anytree.Node("e", parent=a)
c1 = anytree.Node("c", parent=b)
e3 = anytree.Node("e", parent=c1)

r = anytree.resolver.Resolver()

for path in sys.argv[1:]:
    try:
        node = r.get(top, path)
        print(f"path {path} exists: {node}")
    except anytree.resolver.ChildResolverError:
        print(f"path {path} does not exist")

用一个存在的路径来测试上面的代码:

$ python nodes.py /top/a/c/e
path /top/a/c/e exists: Node('/top/a/c/e')

还有一个不存在的路径:

$ python nodes.py /top/a/e/c
path /top/a/e/c does not exist

撰写回答