Reputation: 1298
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?
Upvotes: 4
Views: 3589
Reputation: 1121864
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.
Upvotes: 9