Re: Python 3 __cmp__ semantic change?
On Nov 21, 4:09 am, Duncan Booth <duncan.bo...@i nvalid.invalidw rote:
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__.
On Nov 21, 4:09 am, Duncan Booth <duncan.bo...@i nvalid.invalidw rote:
Johannes Bauer <dfnsonfsdu...@ gmx.dewrote:
>
>
>
I hope you actually have <= here.
>
>
>
>
>
>
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 "Comparison s 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.
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:
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__(ot her) < 0
return self.__cmp__(ot her) < 0
def __le__(self, other):
return self.__cmp__(ot her) < 0
return self.__cmp__(ot her) < 0
I hope you actually have <= here.
>
>
>
def __gt__(self, other):
return self.__cmp__(ot her) 0
return self.__cmp__(ot her) 0
def __ge__(self, other):
return self.__cmp__(ot her) >= 0
return self.__cmp__(ot her) >= 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 "Comparison s 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.
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__.
Comment