@functools.total_ordering in Python

In Python, the total_ordering decorator in the functools module simplifies the development of class comparison methods. This eases the comparison of classes without the need for explicit function definitions, facilitating the specification of various rich comparison operations.

Explicit funcntion definitions refer to the manual creation of functions within a class to handle comparison operations, such as less than (lt), less than or equal to (le), greater than (gt), and greater than or equal to (ge). Traditionally, developers would need to write these functions explicitly for each class, but total_ordering automates this process, allowing for a more concise and readable code structure.

For a class to leverage total_ordering, it must implement a minimum of one of the following comparison methods:

  • __lt__()
  • __le__()
  • __gt__()
  • __ge__()

Additionally, the class must include the eq() method. It is crucial to note that when using total_ordering, it is essential to define at least one comparison method; failure to do so will result in a ValueError exception.

Syntax:

The signature for the total_ordering decorator is as shown below.

@total_ordering

Python @total_ordering Examples:

Example 1:

In this scenario, we will determine the largest among three numbers using the ge function.

from functools import total_ordering
  
@total_ordering
class num:
      
    def __init__(self, value):
        self.value = value
          
    def __ge__(self, other):
        return self.value >= other.value
         
a=10
b=15
c=7

if (num(a) >= num(b)) and (num(a) >= num(c)):
   print(a," is greater than ",b," and ",c)
elif (num(b) >= num(a)) and (num(b) >= num(c)):
   print(b," is greater than ",a," and ",c)
else:
   print(c," is greater than ",a," and ",b) 

Output:

15 is greater than 10 and 7

Example 2:

In this case, we are displaying the prime numbers between 10 and 30. It’s important to note that even though we don’t utilize the lt function for this task, we still need to define at least one of the ordering functions. Failure to do so will result in a ValueError exception.

from functools import total_ordering
  
@total_ordering
class num:
      
    def __init__(self, value):
        self.value = value
    # Not using this function but it's compulsory to define one ordering function     
    def __lt__(self, other):
        return self.value < self.other

    def __eq__(self, other):
        return self.value == other.value
          
l = []
for i in range(10,30):
    if num(i) == num(0) or num(i) == num(1):
        continue
    else:
        for j in range(2, int(i/2)+1):
            if num(i % j) == num(0):
                break
        else:
            l.append(i)

if len(l) == 0:
    print("There are no prime numbers in this range")
else:
    print("The prime numbers in this range are: ", l)

Output

The prime numbers in this range are:  [11, 13, 17, 19, 23, 29]

Example 3:

In this case, we are comparing values of different types, such as a char, a float, a string, an int, etc.

from functools import total_ordering
@total_ordering
class num:
      
    def __init__(self, value):
        self.value = value
    # Not using this function but it's compulsory to define one ordering function     
    def __lt__(self, other):
        return self.value < other.value def __gt__(self, other): return self.value > other.value
    
    def __ne__(self, other):
        return self.value != other.value    

    def __eq__(self, other):
        return self.value == other.value
          
print("Checking A > a ",num('A')>num('a'))
print("Checking 15.5 == 15.59 ",num(15.5)==num(15.59))
print("Checking -10 < -1 ",num(-10)<num(-1))
print("Checking 15 != 15.0 ",num(15)!=num(15.0))
print("Checking Hello == Hello ",num('Hello')==num('Hello'))

Output

Checking A > a  False
Checking 15.5 == 15.59  False
Checking -10 < -1  True
Checking 15 != 15.0  False
Checking Hello == Hello  True

Conclusion:

Therefore, starting from version 3.2 onward, the total_ordering function serves to facilitate the creation of rich class comparison methods. These methods aid in comparing classes without the explicit need to define a function for each comparison

References

Happy Learning 🙂