0
# Node Construction and Tree Building
1
2
Core node classes for building tree structures. This module provides the fundamental building blocks for creating hierarchical data structures with parent-child relationships and tree properties.
3
4
## Capabilities
5
6
### NodeMixin - Base Tree Functionality
7
8
Extends any Python class with tree node functionality. The core mixin that provides parent-child relationships and all tree navigation properties.
9
10
```python { .api }
11
class NodeMixin:
12
"""
13
Extends any Python class to a tree node.
14
15
The only tree relevant information is the parent attribute.
16
If None, the NodeMixin is root node.
17
If set to another node, the NodeMixin becomes the child of it.
18
"""
19
def __init__(self): ...
20
21
# Core tree relationships
22
parent: Optional['NodeMixin']
23
children: Tuple['NodeMixin', ...]
24
25
# Tree navigation properties
26
ancestors: Tuple['NodeMixin', ...]
27
descendants: Tuple['NodeMixin', ...]
28
leaves: Tuple['NodeMixin', ...]
29
root: 'NodeMixin'
30
siblings: Tuple['NodeMixin', ...]
31
32
# Tree state properties
33
is_leaf: bool
34
is_root: bool
35
depth: int
36
height: int
37
path: Tuple['NodeMixin', ...]
38
39
# Methods
40
def iter_path_reverse(self) -> Iterator['NodeMixin']: ...
41
```
42
43
**Usage Example:**
44
45
```python
46
from anytree import NodeMixin, RenderTree
47
48
class MyBaseClass:
49
foo = 4
50
51
class MyClass(MyBaseClass, NodeMixin):
52
def __init__(self, name, length, width, parent=None, children=None):
53
super().__init__()
54
self.name = name
55
self.length = length
56
self.width = width
57
self.parent = parent
58
if children:
59
self.children = children
60
61
# Create tree structure
62
my0 = MyClass('my0', 0, 0)
63
my1 = MyClass('my1', 1, 0, parent=my0)
64
my2 = MyClass('my2', 0, 2, parent=my0)
65
66
print(RenderTree(my0))
67
```
68
69
### Node - Simple Named Node
70
71
A simple tree node with a required `name` attribute and optional keyword arguments. Most commonly used node class for straightforward tree structures.
72
73
```python { .api }
74
class Node(NodeMixin):
75
"""
76
A simple tree node with a name and any kwargs.
77
78
Args:
79
name: A name or any other object this node can reference to as identifier.
80
parent: Reference to parent node.
81
children: Iterable with child nodes.
82
**kwargs: Any other given attribute is just stored as object attribute.
83
"""
84
def __init__(self, name, parent=None, children=None, **kwargs): ...
85
86
name: Any
87
```
88
89
**Usage Example:**
90
91
```python
92
from anytree import Node, RenderTree
93
94
# Create nodes with parent relationships
95
root = Node("root")
96
s0 = Node("sub0", parent=root)
97
s0b = Node("sub0B", parent=s0, foo=4, bar=109)
98
s0a = Node("sub0A", parent=s0)
99
s1 = Node("sub1", parent=root)
100
101
print(RenderTree(root))
102
# Node('/root')
103
# ├── Node('/root/sub0')
104
# │ ├── Node('/root/sub0/sub0B', bar=109, foo=4)
105
# │ └── Node('/root/sub0/sub0A')
106
# └── Node('/root/sub1')
107
108
# Alternative construction using children
109
root = Node("root", children=[
110
Node("sub0", children=[
111
Node("sub0B", bar=109, foo=4),
112
Node("sub0A"),
113
]),
114
Node("sub1")
115
])
116
```
117
118
### AnyNode - Flexible Attribute Node
119
120
A generic tree node with no required attributes, only optional keyword arguments. Useful when you need complete flexibility in node attributes.
121
122
```python { .api }
123
class AnyNode(NodeMixin):
124
"""
125
A generic tree node with any kwargs.
126
127
Keyword Args:
128
parent: Reference to parent node.
129
children: Iterable with child nodes.
130
**kwargs: Any other given attribute is just stored as object attribute.
131
"""
132
def __init__(self, parent=None, children=None, **kwargs): ...
133
```
134
135
**Usage Example:**
136
137
```python
138
from anytree import AnyNode, RenderTree
139
140
# Create nodes with arbitrary attributes
141
root = AnyNode(id="root", type="company")
142
s0 = AnyNode(id="sub0", parent=root, department="engineering")
143
s1 = AnyNode(id="sub1", parent=root, department="marketing", budget=50000)
144
145
print(RenderTree(root))
146
# AnyNode(id='root', type='company')
147
# ├── AnyNode(department='engineering', id='sub0')
148
# └── AnyNode(budget=50000, department='marketing', id='sub1')
149
```
150
151
### LightNodeMixin - Memory-Optimized Node
152
153
A lightweight version of NodeMixin using `__slots__` for reduced memory usage. Provides the same functionality as NodeMixin but with better memory efficiency for large trees.
154
155
```python { .api }
156
class LightNodeMixin:
157
"""
158
A NodeMixin using slots for memory efficiency.
159
"""
160
def __init__(self): ...
161
162
# Same properties and methods as NodeMixin
163
parent: Optional['LightNodeMixin']
164
children: Tuple['LightNodeMixin', ...]
165
# ... (all other NodeMixin properties)
166
```
167
168
### SymlinkNodeMixin - Symbolic Link Node
169
170
Mixin for creating symbolic link nodes that reference other tree nodes. Useful for creating references without duplicating tree structures.
171
172
```python { .api }
173
class SymlinkNodeMixin(NodeMixin):
174
"""
175
Extends any Python class to a symbolic link to a tree node.
176
177
Args:
178
target: Target node this symlink points to.
179
"""
180
def __init__(self, target=None): ...
181
182
target: Optional['NodeMixin']
183
```
184
185
### SymlinkNode - Complete Symbolic Link
186
187
A complete symbolic link node implementation that combines SymlinkNodeMixin functionality with the Node class structure.
188
189
```python { .api }
190
class SymlinkNode(SymlinkNodeMixin):
191
"""
192
Tree node which references to another tree node.
193
"""
194
def __init__(self, target=None, parent=None, children=None): ...
195
```
196
197
**Usage Example:**
198
199
```python
200
from anytree import Node, SymlinkNode, RenderTree
201
202
# Create main tree
203
root = Node("root")
204
sub1 = Node("sub1", parent=root)
205
sub2 = Node("sub2", parent=root)
206
207
# Create symbolic link to sub1
208
link = SymlinkNode(target=sub1, parent=sub2)
209
210
print(RenderTree(root))
211
```
212
213
## Tree Properties Reference
214
215
All node classes inherit these properties from NodeMixin:
216
217
### Relationship Properties
218
219
- **`parent`**: Direct parent node (None for root nodes)
220
- **`children`**: Tuple of direct child nodes
221
- **`ancestors`**: Tuple of all ancestor nodes from parent to root
222
- **`descendants`**: Tuple of all descendant nodes in subtree
223
- **`siblings`**: Tuple of sibling nodes (same parent)
224
- **`leaves`**: Tuple of all leaf nodes in subtree
225
226
### Navigation Properties
227
228
- **`root`**: Root node of the tree
229
- **`path`**: Tuple representing path from root to this node
230
- **`depth`**: Integer depth/level in tree (0 for root)
231
- **`height`**: Integer height of subtree rooted at this node
232
233
### State Properties
234
235
- **`is_root`**: Boolean indicating if node is the root
236
- **`is_leaf`**: Boolean indicating if node has no children
237
238
## Common Patterns
239
240
### Extending Custom Classes
241
242
```python
243
from anytree import NodeMixin
244
245
class Employee(NodeMixin):
246
def __init__(self, name, title, salary, parent=None):
247
super().__init__()
248
self.name = name
249
self.title = title
250
self.salary = salary
251
self.parent = parent
252
253
def __repr__(self):
254
return f"Employee('{self.name}', '{self.title}')"
255
256
# Build organizational chart
257
ceo = Employee("Alice", "CEO", 200000)
258
cto = Employee("Bob", "CTO", 150000, parent=ceo)
259
engineer = Employee("Charlie", "Engineer", 80000, parent=cto)
260
```
261
262
### Dynamic Tree Construction
263
264
```python
265
from anytree import Node
266
267
def build_file_tree(path_data):
268
"""Build tree from path strings"""
269
root = Node("root")
270
271
for path_str in path_data:
272
parts = path_str.split('/')
273
current = root
274
275
for part in parts:
276
# Find or create child
277
child = next((c for c in current.children if c.name == part), None)
278
if not child:
279
child = Node(part, parent=current)
280
current = child
281
282
return root
283
284
paths = ["src/main.py", "src/utils.py", "tests/test_main.py"]
285
tree = build_file_tree(paths)
286
```