On Fri, Nov 21, 2008 at 10:44 AM, Hyuga <[EMAIL PROTECTED]> wrote: > On Nov 21, 4:09 am, Duncan Booth <[EMAIL PROTECTED]> wrote: > > Johannes Bauer <[EMAIL PROTECTED]> wrote: > > > Seems it was removed on purpose - I'm sure there was a good reason for > > > that, but may I ask why? Instead of the sleek __cmp__ function I had > > > earlier, I now have code like: > > > > > def __lt__(self, other): > > > return self.__cmp__(other) < 0 > > > > > def __le__(self, other): > > > return self.__cmp__(other) < 0 > > > > I hope you actually have <= here. > > > > > > > > > def __gt__(self, other): > > > return self.__cmp__(other) > 0 > > > > > def __ge__(self, other): > > > return self.__cmp__(other) >= 0 > > > > > Does anyone know the reason why __cmp__ was discarded? > > > > I think it was because __cmp__ was the backward compatible fallback for > > the newer rich comparison methods and Python 3 cleans up a lot of stuff > > left in just for backward compatibility. In this case it is a cleanup > > too far as in most cases (i.e. those cases where you don't need the full > > complexity of the rich comparisons) __cmp__ is a much simpler solution. > > > > Seehttp://mail.python.org/pipermail/python-dev/2003-March/034073.html > > for Guido's original thoughts. Also, once upon a time pep-3000 referred > > to the removal of __cmp__ but I can't find it in any of the current > > peps. Seehttp:// > mail.python.org/pipermail/python-checkins/2004-August/042959.html > > andhttp:// > mail.python.org/pipermail/python-checkins/2004-August/042972.html > > where the reference to removal of __cmp__ became "Comparisons other than > > ``==`` and ``!=`` between disparate types will raise an exception unless > > explicitly supported by the type" and the reference to Guido's email > > about removing __cmp__ was also removed. > > Guido's primary argument for removing it seems to be that the code for > supporting both __cmp__ and the rich comparisons is "hairy" and that > it felt really satisfying to remove. I don't think that's a good > enough argument. It was hairy because there are a lot of cases to > check, but I wouldn't say it was crufty. It made sense, and the way > it worked seemed logical enough. I never ran into any problems with > it. And by and far the most common case is to implement some total > ordering for a class. > > Now, as has been pointed out, all you really need to define total > ordering, at least for sorting, is __eq__ and __lt__, which isn't too > bad. But you still lose the ability to make any other sort of > comparison without implementing all the other comparison operators > too. > > Perhaps the code could be made somewhat simpler like this: If rich > comparisons are defined, use those and *only* those operators that are > defined, and don't try to fall back on __cmp__ otherwise. If no rich > comparisons are defined, just look for __cmp__. > --
Even easier, make object's rich comparison operators use __cmp__ by default (and object.__cmp__ would raise exceptions since comparisons aren't defined for arbitrary objects). That way, if the rich comparison operators are defined, use those, otherwise use __cmp__. If you only override some of the rich comparison operators and not __cmp__, than trying unsupported operations will raise exceptions. Since everything extends object in 3.0, you wouldn't run into a problem. The only issue I can think of is that if a superclass defines the rich comparison operators, you wouldn't be able to use __cmp__. class object : def __cmp__(self, other): raise NotImplementedError def __lt__(self, other) : return self.__cmp__(other) < 0 def __eq__(self, other): return self.__cmp__(other) > 0
-- http://mail.python.org/mailman/listinfo/python-list