Defining generic classes
The built-in collection classes are generic classes. Generic typeshave one or more type parameters, which can be arbitrary types. Forexample, Dict[int, str]
has the type parameters int
andstr
, and List[int]
has a type parameter int
.
Programs can also define new generic classes. Here is a very simplegeneric class that represents a stack:
- from typing import TypeVar, Generic
- T = TypeVar('T')
- class Stack(Generic[T]):
- def __init__(self) -> None:
- # Create an empty list with items of type T
- self.items: List[T] = []
- def push(self, item: T) -> None:
- self.items.append(item)
- def pop(self) -> T:
- return self.items.pop()
- def empty(self) -> bool:
- return not self.items
The Stack
class can be used to represent a stack of any type:Stack[int]
, Stack[Tuple[int, str]]
, etc.
Using Stack
is similar to built-in container types:
- # Construct an empty Stack[int] instance
- stack = Stack[int]()
- stack.push(2)
- stack.pop()
- stack.push('x') # Type error
Type inference works for user-defined generic types as well:
- def process(stack: Stack[int]) -> None: ...
- process(Stack()) # Argument has inferred type Stack[int]
Construction of instances of generic types is also type checked:
- class Box(Generic[T]):
- def __init__(self, content: T) -> None:
- self.content = content
- Box(1) # OK, inferred type is Box[int]
- Box[int](1) # Also OK
- s = 'some string'
- Box[int](s) # Type error