ActiveState Code

Recipe 476209: Rich Comparison Mixin


The following mixin implements the full suite of rich comparison operators if __cmp__ is defined. See http://docs.python.org/ref/customization.html

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class RichCmpMixin(object):
    """
    Define __cmp__, and inherit from this class to provide full rich
    comparisons.
    """

    def __eq__(self, other):
        return self.__cmp__(other)==0
    
    def __ne__(self, other):
        return self.__cmp__(other)!=0

    def __lt__(self, other):
        return self.__cmp__(other)==-1
    
    def __le__(self, other):
        return self.__cmp__(other)!=1

    def __gt__(self, other):
        return self.__cmp__(other)==1

    def __ge__(self, other):
        return self.__cmp__(other)!=-1

Discussion

The __cmp__ method is sufficient to provide comparisons between user-defined classes. However, inheriting from a base class (such as a builtin) which already provides the rich-comparison methods will cause the derrived __cmp__ not to be used.

Probably needs testing.

Comments

  1. 1. At 3:02 a.m. on 31 mar 2006, Tim Delaney said:

    __cmp__ can return other values. The return values from __cmp__ are negative (less than), 0 (equals) or positive (greater than).

    You therefore can't just compare with -1, 0 and 1 - you need to check < 0, 0 and > 0.

  2. 2. At 10:44 p.m. on 6 apr 2006, Steven Bethard said:

    Sorry, why would you want this? If you define __cmp__, you can already use your object with <, >, !=, etc. so you shouldn't need any of the rich comparisons defined.

    A more useful mixin would be one that defines all the rich comparisons if you just define __eq__ and __lt__. (Python doesn't fill in the missing comparison operators because for some types you can't assume that not &lt; implies >=.)

  3. 3. At 5:07 p.m. on 25 oct 2007, Peter Fein (the author) said:

    Good question. I don't remember why I wrote this.

  4. 4. At 11:41 a.m. on 29 mar 2009, Trent Mick said:

    @steven: My understanding is that __cmp__ is going away in Python 3. I think it is gone as of Python 3.0.1.

Sign in to comment