如何装饰所有继承自元组的比较方法
How to decorate all the comparison methods inheriting from tuple
问题
版本被表示为字符串并在很多地方进行比较。但是由于 ASCII 比较,“5.10”is less than
“5.2”
解决方案
改成tuple
再比较。由于在多个地方进行比较,我想到了从 tuple
继承的自定义 class 并自己处理比较
建议代码
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)
到目前为止,这是我想出的代码,它似乎适用于以下情况:
v1 = Version("5.10")
print(v1 < "5.2")
我的问题是,如何避免对所有其他方法做同样的事情 __le__
、__gt__
等
应该有一个更pythonic的方法来处理other
参数并将其转换为tuple
,然后调用基础class对应的方法
按照评论中的建议,将 inheritance 更改为 composition 并使用 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)
问题
版本被表示为字符串并在很多地方进行比较。但是由于 ASCII 比较,“5.10”is less than
“5.2”
解决方案
改成tuple
再比较。由于在多个地方进行比较,我想到了从 tuple
继承的自定义 class 并自己处理比较
建议代码
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)
到目前为止,这是我想出的代码,它似乎适用于以下情况:
v1 = Version("5.10")
print(v1 < "5.2")
我的问题是,如何避免对所有其他方法做同样的事情 __le__
、__gt__
等
应该有一个更pythonic的方法来处理other
参数并将其转换为tuple
,然后调用基础class对应的方法
按照评论中的建议,将 inheritance 更改为 composition 并使用 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)