Python 3 __cmp__ semantic change?
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Fri Nov 21 20:12:48 EST 2008
On Fri, 21 Nov 2008 17:26:21 +0000, Arnaud Delobelle wrote:
[...]
> As classes can be decorated in Python 3, you can write a decorator to
> make a class totally ordered. Here is a very simplified proof of
> concept such decorator:
>
> def totally_ordered(cls):
> if not hasattr(cls, '__gt__'):
> def gt(self, other):
> return self != other and not self < other
> cls.__gt__ = gt
> # Do the same with __le__, __ge__
> return cls
>
>
> @totally_ordered
> class Fraction:
> def __init__(self, num, den=1):
> assert den > 0, "denomintator must be > 0" self.num = num
> self.den = den
> def __eq__(self, other):
> return self.num*other.den == self.den*other.num
> def __lt__(self, other):
> return self.num*other.den < self.den*other.num
>
>>>> q12=Fraction(1, 2)
>>>> q23=Fraction(2, 3)
>>>> q12 < q23
> True
>>>> q12 > q23
> False
>
> Granted it's not as efficient as a __cmp__ function.
What makes you say that? What do you mean by "efficient"? Are you talking
about memory footprint, runtime speed, disk-space, programmer efficiency,
algorithmic complexity, or something else?
As I see it, a __cmp__ method would be written something like this:
def __cmp__(self, other):
return cmp(self.num*other.den, self.den*other.num)
which presumably would save you a trivial amount of source code (and
hence memory footprint, disk-space and programmer efficiency), but the
algorithmic complexity is identical and the runtime speed might even be
trivially slower due to the extra function call.
If your major concern is to reduce the amount of repeated code in the
methods, then there's no reason why you can't write a __cmp__ method as
above and then call it from your rich comparisons:
def __eq__(self, other):
return self.__cmp__(other) == 0
def __lt__(self, other):
return self.__cmp__(other) < 0
and if you really want to be concise:
__gt__ = lambda s, o: s.__cmp__(o) > 0
__ge__ = lambda s, o: s.__cmp__(o) >= 0
__le__ = lambda s, o: s.__cmp__(o) <= 0
--
Steven
More information about the Python-list
mailing list