The following Python anytree construction
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())
produces this tree:
top
|-- a
| |-- c
| | +-- e
| |-- d
| +-- e
+-- b
+-- c
+-- e
I want to process node a/c/e
under top
if that node exists. If it doesn't exist, I want to get None.
Here is what I have implemented that does what I want:
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}")
The above code returns the following:
Exp match, rcv Node('/top/a/c/e')
Exp None, rcv None
Although the code works, I'm thinking there must be a better way to do it -- something like top.get_descendant("a/c/e")
that would directly access that node instead of searching for it.
What's the right way to access node a/c/e
under node top
(and get None if it doesn't exist)?
Reading through the docs it looks like you want the anytree.resolver
module:
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")
Testing the above code with a path that exists:
$ python nodes.py /top/a/c/e
path /top/a/c/e exists: Node('/top/a/c/e')
And with a path that does not exist:
$ python nodes.py /top/a/e/c
path /top/a/e/c does not exist