1

For convenience, I'd like to use a linked list Node class like the following:

a = Node(3)
b = Node(2, a)
c = Node(1, b) # c = (1) -> (2) -> (3)

I've tried the following class definition

class Node:
    def __init__(self, val: int, next_node: Node = None):
        self.val = val
        self.next = next_node

... but I'm getting a NameError about Node in the constructor.

I recognize that this is recursive, but nevertheless I've seen this done in other languages. Is this possible in Python?

1 Answers1

1

Use typing.Self to refer to the Node type.

from typing import Self
class Node:
    def __init__(self, val: int, next_node: Self = None):

Alternatively, use the string 'Node'.

Unmitigated
  • 76,500
  • 11
  • 62
  • 80
  • Tried that but now getting `ImportError: cannot import name 'Self' from 'typing'`. I've confirmed I have no circular dependencies, any idea? – Max Darling Jan 31 '23 at 04:21
  • @MaxDarling Your Python version might be too low. In that case, just use the string `'Node'` as the type hint. – Unmitigated Jan 31 '23 at 04:22
  • replacing that with `from __future__ import annotations` compiles. taken from [this thread](https://stackoverflow.com/questions/33533148/how-do-i-type-hint-a-method-with-the-type-of-the-enclosing-class). not sure why that works... – Max Darling Jan 31 '23 at 04:24
  • I'm on 3.10.9 :C – Max Darling Jan 31 '23 at 04:25
  • @MaxDarling That works because it'll delay the evaluation of annotations, at which point `Node` is defined. It is essentially the same as using a string to annotate the type (e.g. `'Node'`). – Unmitigated Jan 31 '23 at 04:25