'How to decorate all the comparison methods inheriting from tuple
Problem
Version is being expressed as string and compared at lot of places. But then "5.10" is less than
"5.2" due to ASCII comparison
Solution
Change it to tuple
and then compare. Since comparison is at multiple places, I thought of having a custom class inheriting from tuple
and handle the comparison myself
Proposed code
class Version(tuple):
def __new__(self, v1):
if not isinstance(v1, tuple):
v1 = tuple(map(lambda x: int(x), v1.split('.')))
return tuple.__new__(Version, v1)
def __lt__(self, other):
if not isinstance(other, tuple):
other = tuple(map(lambda x: int(x), other.split('.')))
return super().__lt__(other)
def __repr__(self):
return '.'.join(str(x) for x in self)
This is the code I came up with, so far, and it seems to work fine for cases like:
v1 = Version("5.10")
print(v1 < "5.2")
The question I have is, how can I avoid doing the same thing for all the other methods __le__
, __gt__
etc.
There should be a more pythonic way to just massage the other
argument and convert it to tuple
, then call the base class corresponding method
Solution 1:[1]
As suggested in the comments, changed inheritance to composition and used total_ordering
from functools import total_ordering
@total_ordering
class Version():
def __init__(self, v1):
self.v1 = tuple(map(lambda x: int(x), v1.split('.')))
def __eq__(self, other):
if not isinstance(other, tuple):
other = tuple(map(lambda x: int(x), other.split('.')))
return self.v1 == other
def __lt__(self, other):
if not isinstance(other, tuple):
other = tuple(map(lambda x: int(x), other.split('.')))
return self.v1 < other
def __repr__(self):
return '.'.join(str(x) for x in self.v1)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |