Say I want to write a comparison sorting function, I can hint that the input must be a sequence with Sequence[T]
(or MutableSequence[T]
in this case).
from typing import MutableSequence, T
def comparison_sort(s: MutableSequence[T]) -> None:
pass
However there does not seems to be an out-of-the box way to hint that T
must be comparable. (There is no Comparable
or Ordered
or anything it seems in typing
.) How can I achieve this? I would like to avoid specifying a specific set of types, like int
, float
, 'str` so that a user could also hint that their own type is comparable.
Introduction to Python type hints It means that you need to declare types of variables, parameters, and return values of a function upfront. The predefined types allow the compilers to check the code before compiling and running the program.
Type hinting is the process of annotating your code so that other developers reading your code will understand the type of an object declared. Type hinting was officially added with the release of Python 3.5.
Not enforced at runtime They can be used by third party tools such as type checkers, IDEs, linters, etc.
Type hints work best in modern Pythons. Annotations were introduced in Python 3.0, and it's possible to use type comments in Python 2.7. Still, improvements like variable annotations and postponed evaluation of type hints mean that you'll have a better experience doing type checks using Python 3.6 or even Python 3.7.
As noted in the comments, Comparable
isn't a state of being, it's only meaningful as a descriptor for a pair of types. Usually, a sorting function is working with homogeneous types though, so as long as you don't mind the type checker only handling the concept of "supports <
with some types" rather than "supports <
with arbitrary types", you can define your own Comparable
and bound a typing
TypeVar
with it. Conveniently, PEP484 (which defines typing
hints) already provides an example of how you'd do this:
from abc import ABCMeta
from typing import Any, TypeVar
class Comparable(metaclass=ABCMeta):
@abstractmethod
def __lt__(self, other: Any) -> bool: ...
CT = TypeVar('CT', bound=Comparable)
You can then use this for your comparable_sort
definition with:
def comparable_sort(s: MutableSequence[CT]) -> None:
Note that I only required __lt__
to be defined; as a rule, Python 3 implements its own sorting functions entirely in terms of __lt__
(it doesn't use any of the other rich comparator operators, not even __eq__
)†, so it's a good idea to design your own algorithm the same way, so anything sorted
can handle, you can handle the same way.
†: Python 2 originally used __le__
in at least one place (heapq
), but it's been intentionally, consistently, __lt__
for the builtins and standard library in the Python 3 timeframe, and your style of typing is Python 3-only anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With