Generics/templates in python?
The other answers are totally fine:
- One does not need a special syntax to support generics in Python
- Python uses duck typing as pointed out by André.
However, if you still want a typed variant, there is a built-in solution since Python 3.5.
Generic classes:
from typing import TypeVar, Generic, ListT = 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
# Construct an empty Stack[int] instancestack = Stack[int]()stack.push(2)stack.pop()stack.push('x') # Type error
Generic functions:
from typing import TypeVar, SequenceT = TypeVar('T') # Declare type variabledef first(seq: Sequence[T]) -> T: return seq[0]def last(seq: Sequence[T]) -> T: return seq[-1]n = first([1, 2, 3]) # n has type int.
Static type checking:
You must use a static type checker
such as mypy to analyze your source code.
Install mypy:
python3 -m pip install mypy
Analyze your source code, for example a certain file:
mypy foo.py
or directory:
mypy some_directory
mypy will detect and print type errors. A concrete output for the Stack example provided above:
foo.py:23: error: Argument 1 to "push" of "Stack" has incompatible type "str"; expected "int"
References: mypy documentation about generics and running mypy
Python uses duck typing, so it doesn't need special syntax to handle multiple types.
If you're from a C++ background, you'll remember that, as long as the operations used in the template function/class are defined on some type T
(at the syntax level), you can use that type T
in the template.
So, basically, it works the same way:
- define a contract for the type of items you want to insert in the binary tree.
- document this contract (i.e. in the class documentation)
- implement the binary tree using only operations specified in the contract
- enjoy
You'll note however, that unless you write explicit type checking (which is usually discouraged), you won't be able to enforce that a binary tree contains only elements of the chosen type.
Actually now you can use generics in Python 3.5+.See PEP-484 and typing module documentation.
According to my practice it is not very seamless and clear especially for those who are familiar with Java Generics, but still usable.