Command Palette

Search for a command to run...

Hectal
Back to the lesson: Topic 10.4 — Generics and Type Variables
Python · Example 2 of 2 Python 3.12+

A generic Stack, bounds and constraints

Stack[int] is a hint only: the string still goes in at run time. Constraints and bounds are stored on the type variable.

A generic function or class works for many types while keeping track of which: first([1, 2]) gives an int, first(['a']) gives a str. You declare the placeholder with TypeVar or, since Python 3.12, with the clean def f[T](x: T) and class Box[T] syntax.

Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.

Ready for more? This phase has 5 hands-on exercises with automatic checks.

Practice questions

Write the code in the editor, run it, then open the model answer to compare.

01

Write last[T](items: Sequence[T]) -> T and print last([1, 2, 3]) and last("hey").

02

Write class Pair[A, B] holding two values, with a method swap() returning a Pair[B, A], and print the swapped pair's items.

03

Write type Matrix = list[list[float]] and a function that returns the sum of every number in it.

Explain it without notes

01

What problem does a type variable solve?

02

What is the difference between a bound and constraints on a type variable?

03

Does Stack[int]() stop you pushing a string at run time? Why or why not?

04

How do the 3.12 generic syntax and TypeVar differ?

05

Explain variance: why is list[Dog] not a list[Animal], and what is the 3.12 syntax's advantage there?

A generic Stack, bounds and constraints Python 3.12+
Sign in to run this example in your browser.

Expected output

2 1
class without [int]: <class '__main__.Stack'> | with: __main__.Stack[int]
items now: [1, 'oops']
9 2.5 coffee
constraints: (<class 'int'>, <class 'float'>)
bound: <class 'str'>
old style bound: typing.Hashable