I'm trying to create a tree structure with python typing annotation. The code is like this:
from typing import List
class TNode:
def __init__(self, parent: 'TNode', data: str, children: List['TNode'] = []):
self.parent = parent
self.data = data
self.children = children
root = TNode(None, 'example')
But the code has a issue of type mismatching, Pycharm will raise Expected type 'TNode', got 'None' instead. Is there a way to solve this issue, or if there is a better way to design the class constructor?
If your parent node can be None, you need to mark the argument as Optional or explicitly use a Union[None, 'TNode'] annotation:
from typing import List, Optional
class TNode:
def __init__(self, parent: Optional['TNode'], data: str, children: List['TNode'] = []) -> None:
Side note: you probably do not want to use [] as a default value for children. Defaults are evaluated once and stored with the function object, so if you were to use the default value and mutate it, you mutate the shared default. See "Least Astonishment" and the Mutable Default Argument.
Set children to a default None sentinel value instead:
class TNode:
def __init__(
self,
parent: Optional['TNode'],
data: str,
children: Optional[List['TNode']] = None
) -> None:
self.parent = parent
self.data = data
self.children = children or []
The children or [] expression will set self.children to an empty list whenever the children argument is a falsey value, including None and an empty list.
I also used a different formatting for the argument list, better suited for type-annotated arguments where the line length would exceed the recommended 80 characters line length limit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With