Python Generics & TypeVar
A generic is code written once to work safely with many types.
One placeholder, one link
T stands for the item type. The return hint uses the same T.
from typing import TypeVar
T = TypeVar("T")
def first(items: list[T]) -> T:
return items[0]
print(first([10, 20, 30]))
print(first(["red", "green"]))Same type in, same type out
keep returns the type it was given. A checker sees an int stay an int.
from typing import TypeVar
T = TypeVar("T")
def keep(value: T) -> T:
return value
print(keep(42))
print(keep("hello"))A generic class
Stack takes the item type in brackets. This stack is a stack of ints.
from typing import Generic, TypeVar
T = TypeVar("T")
class Stack(Generic[T]):
def __init__(self) -> None:
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
numbers = Stack[int]()
numbers.push(10)
numbers.push(20)
print(numbers.pop())A bounded placeholder
bound=int limits NumT for a checker. Only int and its subtypes fit the hint.
from typing import TypeVar
NumT = TypeVar("NumT", bound=int)
def double(value: NumT) -> NumT:
return value * 2
print(double(21))
print(double(5))Example
from typing import Generic, TypeVar
T = TypeVar("T")
def first(items: list[T]) -> T:
return items[0]
class Stack(Generic[T]):
def __init__(self) -> None:
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
numbers = Stack[int]()
numbers.push(10)
numbers.push(20)
print(numbers.pop())
print(numbers.pop())
print(first(["red", "green"]))
print(first([3, 9]))Key points
- Generic: code written once to work safely with many types
- TypeVar: a placeholder name that stands for one real type
- Use the same TypeVar in two places to tie those types together
- Use Generic[T] to make a class work with a chosen item type
- Bounded TypeVar: a TypeVar limited to a type and its subtypes
- TypeVars guide a type checker in Python
In this example, first uses T to link its input and output. Stack is a generic class that stores items in a list. The numbers stack accepts ints through its hint. pop returns the last item pushed, so 20 prints first. first then works on words and on numbers. The same T link holds for both calls.
Note
They do not change how the code runs.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Python Playground
Exercise
What does the T in def first(items: list[T]) -> T tell a checker?