Home > Software engineering >  How to return the class type in python using generics?
How to return the class type in python using generics?

Time:04-30

I'm creating a List class in python (a List like java lists) using generics. The class node is also generic and I'm creating the getters and setters methods for the prev and next node. I was wondering how could I return a type like the class node itself? This is my progress:

from typing import Generic, TypeVar                                                                                                                                                           
T = TypeVar('T')                                                                                               
                                                                                                               
class Node(Generic[T]):                                                                                        
    ''' Generic class Node. It models a node for a linked list. '''                                            
                                                                                                               
    def __init__(self, element: T) -> None:                                                                    
        ''' Constructor. It recives an element of type T.'''                                                   
        self.element = element                                                                                 
        self.next = None                                                                                       
        self.prev = None                                                                                       
                                                                                                               
    def get_item(self) -> T:                                                                                   
        ''' Returns the item in the node.'''                                                                   
        return self.element                                                                                    
                                                                                                               
    def get_prev(self) -> #What is the type I should return here?:                                                                             
        ''' Returns the previous node.'''                                                                      
        return self.prev                                                                                       
                                                                                                               
    def get_next(self) -> #What is the type I should return here?:                                                                             
        ''' Return the next node.'''                                                                           
        return self.next                                                                                       
                                                                                                               
    def set_prev(self, prev) -> None:                                                                          
        ''' Changes the previous element to the specified node.'''                                             
        self.prev = prev                                                                                       
                                                                                                               
    def set_next(self, next) -> None:                                                                          
        ''' Changes the next element to the specified node.'''                                                 
        self.next = next       

I've tried with

    def get_prev(self) -> Node[T]:                                                                             
        ''' Returns the previous node.'''                                                                      
        return self.prev                                                                                       
                                                                                                               
    def get_next(self) -> Node[T]:                                                                             
        ''' Return the next node.'''                                                                           
        return self.next                                                                                                                                                                                                      

But it gives me the error

Traceback (most recent call last):
  File "List.py", line 5, in <module>
    class Node(Generic[T]):
  File "List.py", line 18, in Node
    def get_prev(self) -> Node[T]:
NameError: name 'Node' is not defined

CodePudding user response:

I think the newest Python versions have the capability of self-referencing classes in type annotations (here, get_prev's return type Node that is currently being defined).

Older Python versions, down to 3.7, still support it by adding:

from __future__ import annotations

see: https://peps.python.org/pep-0563/#enabling-the-future-behavior-in-python-3-7

  • Related