Reputation: 21418
What is the most natural way to complete the following code?
import functools
@functools.total_ordering
class X:
def __init__(self, a):
self._a = a
def __eq__(self, other):
if not isinstance(other, X):
return False
return self._a == other._a
def __lt__(self, other):
if not isinstance(other, X):
return ... // what should go here?
return self._a < other._a
if __name__ == '__main__':
s = [2, 'foo', X(2)]
s.sort()
print s
Upvotes: 5
Views: 427
Reputation: 1124000
You can choose whatever feels natural to you; False
means your instances always sort after other types, True
and they'll be sorted before.
Alternatively, you can return NotImplemented
(see the __lt__
and other comparison methods documentation) to signal the comparison is not supported:
def __lt__(self, other):
if not isinstance(other, X):
return NotImplemented
return self._a < other._a
Quoting the documentation:
A rich comparison method may return the singleton
NotImplemented
if it does not implement the operation for a given pair of arguments. By convention,False
andTrue
are returned for a successful comparison. However, these methods can return any value, so if the comparison operator is used in a Boolean context (e.g., in the condition of an if statement), Python will callbool()
on the value to determine if the result is true or false.
Upvotes: 3
Reputation: 15990
My personal approach:
An exception.
There's no natural order between different types.
The official one: (choose this one, there should be)
Although I don't agree with that completely, the manual clearly states how it should be done:
http://docs.python.org/library/stdtypes.html#comparisons
Objects of different types, except different numeric types and different string types, never compare equal; such objects are ordered consistently but arbitrarily (so that sorting a heterogeneous array yields a consistent result). Furthermore, some types (for example, file objects) support only a degenerate notion of comparison where any two objects of that type are unequal. Again, such objects are ordered arbitrarily but consistently. The <, <=, > and >= operators will raise a TypeError exception when any operand is a complex number.
So basically... I would raise an exception, but the most pythonic way of doing the ordering would be to comply with the manual.
There should be one-- and preferably only one --obvious way to do it.
Upvotes: 3