🎓 A1Learner
🔍

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?