With abstract base classes, Python provides a way to know the behavior of objects without actually trying it out. In the standard library, we have some ABCs defined for containers in collections.abc. For example, one can test that an argument is iterable:
from collections.abc import Iterable
def function(argument):
if not isinstance(argument, Iterable):
raise TypeError('argument must be iterable.')
# do stuff with the argument
I was hoping that there would be one such ABC for deciding whether instances of a class can be compared but couldn't find one. Testing for the existence of __lt__
methods is not sufficient. For example, dictionaries cannot be compared but __lt__
is still defined (same with object
actually).
>>> d1, d2 = {}, {}
>>> d1 < d2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: dict() < dict()
>>> hasattr(d1, '__lt__')
True
So my question is: is there a simple way to do it without doing the comparisons themselves and catching the TypeError
?
My use case is similar to a sorted container: I'd like to raise an exception when I insert the first element and not to wait for a second element. I thought about comparing the element with itself, but is there a better approach:
def insert(self, element):
try:
element < element
except TypeError as e:
raise TypeError('element must be comparable.')
# do stuff