0

I have following class:

class Word:
    def __init__(self, key: str):
        self.key = key
        self.value = ''.join(sorted(key))

    def __lt__(self, other):
        if self.value < other.value:
            return True
        return False

    def __gt__(self, other):
        if self.value > other.value:
            return True
        return False

    def __eq__(self, other):
        val = other.value
        if self.value == val:
            return True
        return False

and < works. But when I try <= I get following error:

TypeError: '<=' not supported between instances of 'Word' and 'Word'

How to override <= for python class?

evgenyorlov1
  • 225
  • 5
  • 15
  • 1
    You might want to use the decorator [`functools.total_ordering`](https://docs.python.org/3.8/library/functools.html#functools.total_ordering). – Matthias Apr 14 '20 at 11:49

3 Answers3

1

You need to implement __ge__ & __le__

class Word:
    def __init__(self, key: str):
        self.key = key
        self.value = ''.join(sorted(key))

    def __lt__(self, other):
        if self.value < other.value:
            return True
        return False

    def __gt__(self, other):
        if self.value > other.value:
            return True
        return False

    def __le__(self, other):
        if self.value <= other.value:
            return True
        return False

    def __ge__(self, other):
        if self.value >= other.value:
            return True
        return False

    def __eq__(self, other):
        val = other.value
        if self.value == val:
            return True
        return False
rdas
  • 20,604
  • 6
  • 33
  • 46
1

You need to override def __le__(self, other) (lesser-equal) and def __ge__(self, other) (greater equal) as well.

Beside that you should check if your given other actually is a Word instance, else you might crash because no other.value can be accessed:

w = Word("hello")
print( w > 1234 )  # crash:  AttributeError: 'int' object has no attribute 'value'

Source / Documentation of all of them: object.__le__

See


Potential fix for comparison:

def __lt__(self, other):
    if isinstance(other, Word):
        if self.value < other.value:
            return True
    else:
        # return True or False if it makes sense - else use better exception
        raise ValueError(f"Cannot compare Word vs. {type(other)}")
    return False
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
1

There is another special method for this:

 def __le__(self, other):
    if self.value <= other.value:
        return True
    else:
        return False