[Python-ideas] a sorting protocol dunder method?

Steven D'Aprano steve at pearwood.info
Mon Dec 4 06:41:40 EST 2017

On Sun, Dec 03, 2017 at 10:48:18PM -0800, Carl Meyer wrote:
> I think this is an interesting idea, and I don't believe that either
> performance or "sortable vs comparable" are very relevant.

Performance is always relevant -- while performance shouldn't be the 
sole deciding factor, it should be a factor.

And since the entire use-case for this is sorting versus comparison 
operators, I'm having trouble understanding why you think that sorting 
versus comparison operators is irrelevant.

> I doubt there is much performance to gain here,

I doubt there is any performance gain -- rather a performance hit is far 
more likely.

> and I think the default sort order for
> a class must continue to match its comparison behavior.

This proposal changes that: if a class defines __key__ but not __lt__, 
then the default sort behaviour will be different from the comparison 

If it defines both, it isn't clear which will be used for sorting. 
Should __lt__ take priority, or __key__? Whichever we choose, somebody 
is going to be upset and confused by the choice.

> Most often when I define equality and comparison dunder methods for a
> custom class, I'm effectively just deferring the comparison to some
> field or tuple of fields of the object. E.g.
>     from functools import total_ordering
>     @total_ordering
>     class BankAccount:
>         def __init__(self, balance):
>             self.balance = balance

[snip example]

This example shows exactly the confusion of concepts I'm talking about. 
Why should bank accounts be sorted by their balance, instead of by their 
account number, or account name, or date they were opened?

Why should BankAccounts sort differently according to their balance, a 
quantity which can change after every transaction? What happens when 
somebody decides that bank accounts default sorting should be by their 
account name rather than the ever-changing balance?

I'm not saying that it never makes sense to sort a bunch of accounts 
according to their balance. I'm saying that functionality is not part of 
the account themselves. If it belongs anywhere, it belongs in the 
collection of accounts. And even that is dubious: I believe that where 
it really belongs is in the report generator that needs to sort the 
collection of accounts.

> It'd be nice to be able to eliminate an import

That's an argument that applies to *literally* everything in the 
standard library. Should we make everything a built-in?

The prerequisites for eliminating the need for an import should be a 
*lot* higher than just "it would be nice".

I disagree with the design of this: it is putting the decision of how to 
sort uncomparable objects in the wrong place, in the object itself 
rather than in the report that wants to sort them.


More information about the Python-ideas mailing list