[Python-ideas] Automatic total ordering
George Sakkis
george.sakkis at gmail.com
Wed Oct 15 23:36:56 CEST 2008
On Wed, Oct 15, 2008 at 4:50 PM, Arnaud Delobelle <arnodel at googlemail.com>wrote:
>
> On 15 Oct 2008, at 19:35, George Sakkis wrote:
>
> On Wed, Oct 15, 2008 at 2:11 PM, Guido van Rossum <guido at python.org>
>> wrote:
>>
>> On Wed, Oct 15, 2008 at 11:03 AM, Terry Reedy <tjreedy at udel.edu> wrote:
>> > George Sakkis wrote:
>> >>
>> >> Now that 3.x fixes the arbitrary object comparison wart and drops (?)
>> >> __cmp__,
>> >
>> > An entry for __cmp__ was in the 3.0c1 doc, which confused me.
>> > It is now gone in
>> >
>> http://docs.python.org/dev/3.0/reference/datamodel.html#special-method-names
>> >
>> > Since rich comparisons are defined on object and are inherited by all
>> > classes, it would be difficult to make them not defined.
>>
>> I should also note that part of George's proposal has already been
>> implemented: if you define __eq__, you get a complementary __ne__ for
>> free. However it doesn't work the other way around (defining __ne__
>> doesn't give you __eq__ for free), and there is no similar
>> relationship for the ordering operators. The reason for the freebie is
>> that it's *extremely* unlikely to want to define != as something other
>> than the complement of == (the only use case is IEEE compliant NaNs);
>> however it's pretty common to define non-total orderings (e.g. set
>> inclusion).
>>
>> Partial orderings are certainly used, but I believe they are far less
>> common than total ones. Regardless, a partially ordered class has to
>> explicitly define the supported methods with the desired semantics anyway;
>> the proposed change wouldn't make this any harder.
>>
>
> I don't understand. In a mathematical ordering,
>
> * x > y means the same as y < x
> * x <= y means the same as x < y or x = y
> * x >= y means the same as x > y or x = y
>
> and this is irrespective of whether the ordering is partial or total.
>
> So, given __eq__ and __lt__, all the rest follows. E.g.
>
> def __gt__(self, other):
> return other.__lt__(self)
> etc...
>
> Where am I going wrong?
For total orderings, one can define all methods in terms of self.__eq__ and
self.__lt__, i.e. avoid making any assumption about `other`, e.g:
def __gt__(self, other):
return not (self == other or self < other)
Your __gt__ definition (which is also what Michael Foord does in his class
decorator) may break mysteriously:
class Thing(object):
def __init__(self, val):
self.val = val
@total_ordering
class Thing_lt(Thing):
def __lt__(self, other):
return self.val < other.val
>>> t1 = Thing_lt(1)
>>> t2 = Thing(2)
>>> t1 < t2
True
>>> t1 > t2
...
RuntimeError: maximum recursion depth exceeded
George
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20081015/ffb58347/attachment.html>
More information about the Python-ideas
mailing list