Overview Python 3.12 introduces a major syntax overhaul for Generics, making it easier than ever to write flexible, reusable code. Generics allow you to parameterize classes and functions with types, ensuring your data structures remain consistent without sacrificing the power of static type checking. Unlike using the `any` type, which effectively turns off type safety, generics preserve the relationship between inputs and outputs. Prerequisites To get the most out of this tutorial, you should have a basic understanding of Python class definitions and methods. Familiarity with Type Annotations is helpful, as generics are an extension of the broader typing system designed to catch bugs before they reach production. Key Libraries & Tools No external libraries are required. You only need the Python 3.12 standard library. Tools like Mypy or integrated development environment (IDE) hover features (like those in VS Code) are essential for seeing these type checks in action. Code Walkthrough In previous versions, you had to import and define `TypeVar`. In 3.12, the syntax is significantly cleaner. We can define a generic `Stack` by placing the type parameter directly in brackets after the class name. ```python class Stack[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() ``` When you instantiate `Stack[int]()`, the methods automatically adapt. The `push` method now explicitly expects an integer. This prevents a common headache: accidentally mixing strings into a list intended for numerical calculations. Constrained Type Parameters You can restrict what types a generic class accepts by using a tuple of allowed types. This is particularly useful when you need to ensure a class only handles numeric data for operations like summation. ```python class NumericStackT: (int, float): def average(self) -> float: return sum(self.items) / len(self.items) ``` By defining `T: (int, float)`, you tell the type checker that `NumericStack[str]` is invalid. Note that this is different from a `Union`. A `Union[int, float]` creates a stack that can contain a mix of both; a generic `T` restricted to `(int, float)` means the stack must be consistently all integers or all floats. Tips & Gotchas Always remember that Python remains a dynamically typed language at runtime. While your IDE will highlight a type violation in red if you pass a string to a `Stack[int]`, the Python Interpreter will still execute the code. Type hints are a development-time safety net, not a runtime enforcement mechanism.
Python Interpreter
Products
- Apr 2, 2024
- Jul 28, 2023