gpt4 book ai didi

python >= 类上的运算符

转载 作者:行者123 更新时间:2023-12-01 04:44:26 27 4
gpt4 key购买 nike

我有一个关于 python '>=' 行为的问题。

我有一个旧的 TimeStamp 类,它保存(小时,分钟)元组并提供一些方法,例如 __eq____gt____lt__ .

我正在重构它以考虑天和秒,并将数据存储为总秒数。这里我还实现了__eq____gt____lt__

但是,在代码中,我在该类中使用 >= 运算符,并且在旧类版本正常工作的同时,我得到了新版本

TypeError: unorderable types: TimeStamp() >= TimeStamp() error.

代码如下:

class TimeStamp(tuple): # OLD, WORKING VERSION
"""TimeStamp, hh:mm tuple supporting comparison and addition"""
__slots__ = ()
def __new__(cls, *args):
if len(args) == 1: # tuple entrance
hour, minute = args[0]
elif len(args) == 2: # hour, minute entrance
hour, minute = args[0], args[1]
else:
raise TypeError('wrong input to TimeStamp')
div, minute = divmod(minute, 60)
hour += div
_, hour = divmod(hour, 24)
return tuple.__new__(cls, (hour, minute))

@property
def abs_min(self):
return self.hour * 60 + self.minute

def __gt__(self, rhs):
return self.abs_min > rhs.abs_min

def __lt__(self, rhs):
return self.abs_min < rhs.abs_min

def __eq__(self, rhs):
return self.abs_min == rhs.abs_min

新版本:

class TimeStamp:
def __init__(self, *args):
for argument in args:
if not isinstance(argument, int):
raise TypeError("Can only build TimeStamp from ints, not: " + str(argument))

if len(args) == 1: # init by abs
self.abs = args[0] # put the ELEMENT, not the tuple itself
elif len(args) == 2: # init by hour:minute
hour, minute = args
self.abs = hour * 60 * 60 + minute * 60
elif len(args) == 4: #init by day:hour:minute:second
day, hour, minute, second = args
self.abs = day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second
else:
raise TypeError("wrong data for TimeStamp: " + str(args))

def __eq__(self, other):
if isinstance(other, TimeStamp):
return self.abs == other.abs
else:
raise TypeError("wrong argument for comparison: " + str(other))

def __gt__(self, other):
if isinstance(other, TimeStamp):
return self.abs > other.abs
else:
raise TypeError("wrong argument for comparison: " + str(other))

def __lt__(self, other):
if isinstance(other, TimeStamp):
return self.abs < other.abs
else:
raise TypeError("wrong argument for comparison: " + str(other))

现在进行比较部分:

if args[1] >= self.start:
>>TypeError: unorderable types: TimeStamp() >= TimeStamp()

我发现了两个修复:首先,将我的比较行替换为

if args[1] > self.start or args[1] == self.start:

或者替代方案,添加

def __ge__(self, other):
if isinstance(other, TimeStamp):
return self.abs >= other.abs
else:
raise TypeError("wrong argument for comparison: " + str(other))

到我的新类(class)。然而,旧版本并没有解决这些问题。在我看来,Python 似乎停止演绎 ((a>b) 或 (a==b)) 暗示 (a>=b)。但为什么之前能用呢?这与我对元组进行子类化有什么关系吗?

PS。不要被我的 __init__ 代码吓到,我将其包含在内是为了完整性。它应该是类似重载的,但我可能会以非Pythonic的方式来做(仍在学习)

最佳答案

旧的可以工作,因为它继承自tuple,而tuple提供了__ge__。您的新版本不是从 tuple 继承的,因此它没有 __ge__ 方法。

即使在您的旧版本中,您的 __gt____lt__ 方法在使用 >= 时也不会被调用(您可以通过输入来验证)在这些方法中打印)。而是调用了底层的 tuple.__ge__ 。但是,对于您的情况,效果是相同的,所以您没有注意到。也就是说,鉴于“分钟”数字始终小于 60,以通常的方式比较 (hours, 分钟) 元组相当于比较 60*小时 + 分钟 。因此,如果您继承自 tuple,我认为您根本不需要定义比较方法。

关于python >= 类上的运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29807242/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com