как сравнивать версии ПО с помощью Python?
Нужно написать класс Version. чтобы создавать экземпляры и потом иметь возможность сравнивать их между собой как версии. Пример:
Version('1.1.3') < Version('2.2.3')
# True
Version('1.3.0') > Version('0.3.0')
# True
Насколько я понимаю, нужно переопределить методы le и т.п. но не совсем понимаю как это сделать. Провбовал импортировать from distutils.version import Version, LooseVersion, StrictVersion. но мне нужно именно написать свой класс
Ответы (2 шт):
Берем класс, в котором всё есть и делаем из него свой:
class Version(tuple):
def __new__(cls, text):
return super().__new__(cls, tuple(int(x) for x in text.split('.')))
__new__ потому как tuple инициализируется до __init__
>>> Version('1.1.3') < Version('2.2.3')
True
>>> Version('1.3.0') > Version('0.3.0')
True
Для наглядности методов сравнения реализуются функции
class Version:
def __init__(self, text):
self.version = tuple(int(x) for x in text.split('.'))
def __le__(self, other):
return self.version <= other.version
def __ge__(self, other):
return self.version >= other.version
def __lt__(self, other):
return self.version < other.version
def __gt__(self, other):
return self.version > other.version
def __eq__(self, other):
return self.version == other.version
def __str__(self):
return '.'.join(self.version)
Но если версии разной длинны нужно вводить функцию сравнения:
import itertools
class Version:
def __init__(self, text):
self.version = tuple(int(x) for x in text.split('.'))
def __le__(self, other):
return self.__cmp(other.version) <= 0
def __ge__(self, other):
return self.__cmp(other.version) >= 0
def __lt__(self, other):
return self.__cmp(other.version) < 0
def __gt__(self, other):
return self.__cmp(other.version) > 0
def __eq__(self, other):
return self.__cmp(other.version) == 0
def __cmp(self, b):
a = self.version
for x,y in itertools.zip_longest(a, b, fillvalue=0):
if x != y:
return x - y
return 0
Тогда
>>> Version('1.1') == Version('1.1.0')
True
В итоге пришел к этому. Просто нашел еще ,что версии могут содержать буквы и слова типо alpha и т.п.
class Version:
def __init__(self, version):
"""
The versions are reduced to a format of five numeric values separated by a dot.
1.2.0.0.0
The class returns a tuple.
:param version: str
:return tuple: ('*','*','*','*','*')
"""
lst = version.split('.')
version_lst = []
for ind in lst:
verbal_version = re.findall('[a-z]{1,5}', ind)
if verbal_version != []:
try:
temp_val = verbal_version[0]
if temp_val == 'a' or temp_val == 'alpha':
r = 0
elif temp_val == 'b' or temp_val == 'beta':
r = 1
elif temp_val == 'rc':
r = 2
elif temp_val == 'r':
r = 3
else:
raise ValueError
except ValueError:
print('Undefined version')
break
digital_version = re.findall('\d{1,5}', ind)
if digital_version != []:
version_lst.append(digital_version[0])
version_lst.append(r)
else:
version_lst.append(ind)
while len(version_lst) < 5:
version_lst.append('0')