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 -- http://mail.python.org/mailman/listinfo/python-list