python >= operator on classes -
i have question regarding python '>=' behaviour.
i have old timestamp class, holds (hour, minute) tuple , offers methods such __eq__
, __gt__
, __lt__
.
i refactoring account day , second, , store data total seconds. here implemented __eq__
, __gt__
, __lt__
well.
however, further in code using >= operator class , while old class version working properly, new 1 getting
typeerror: unorderable types: timestamp() >= timestamp() error.
code below:
class timestamp(tuple): # old, working version """timestamp, hh:mm tuple supporting comparison , 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 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
new version:
class timestamp: def __init__(self, *args): argument in args: if not isinstance(argument, int): raise typeerror("can build timestamp ints, not: " + str(argument)) if len(args) == 1: # init abs self.abs = args[0] # put element, not tuple elif len(args) == 2: # init hour:minute hour, minute = args self.abs = hour * 60 * 60 + minute * 60 elif len(args) == 4: #init 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 timestamp: " + str(args)) def __eq__(self, other): if isinstance(other, timestamp): return self.abs == other.abs else: raise typeerror("wrong argument comparison: " + str(other)) def __gt__(self, other): if isinstance(other, timestamp): return self.abs > other.abs else: raise typeerror("wrong argument comparison: " + str(other)) def __lt__(self, other): if isinstance(other, timestamp): return self.abs < other.abs else: raise typeerror("wrong argument comparison: " + str(other))
now comparison part:
if args[1] >= self.start: >>typeerror: unorderable types: timestamp() >= timestamp()
i have found 2 fixes: first, replace comparison line with
if args[1] > self.start or args[1] == self.start:
or alternative, add
def __ge__(self, other): if isinstance(other, timestamp): return self.abs >= other.abs else: raise typeerror("wrong argument comparison: " + str(other))
to new class. however, old 1 did work neither of fixes. looks me if python stopped deducting ((a>b) or (a==b)) implies (a>=b). why did work before? have me subclassing tuple?
ps. don't scared __init__
code, included completeness. it's supposed overload-like, might doing in non-pythonic way (still learning)
the old 1 worked because inherited tuple
, , tuple
provides __ge__
. new version not inherit tuple
, doesn't have __ge__
method.
even in old version, __gt__
, __lt__
methods never being called when using >=
(as can verify putting print
inside methods). underlying tuple.__ge__
being called instead. however, case, effect same, didn't notice. is, given "minutes" number less 60, comparing (hours, minutes)
tuples in usual way equivalent comparing 60*hours + minutes
. don't think need define comparison methods @ if inherit tuple.
Comments
Post a Comment