[Python-ideas] a sorting protocol dunder method?

Carl Meyer carl at oddbird.net
Mon Dec 4 01:48:18 EST 2017


I think this is an interesting idea, and I don't believe that either
performance or "sortable vs comparable" are very relevant. I doubt there
is much performance to gain here, and I think the default sort order for
a class must continue to match its comparison behavior.

I think the case in favor of this idea (slightly modified, so it no
longer applies only to sorting) is mostly convenience and readability.

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

        def __eq__(self, other):
            if isinstance(other, BankAccount):
                return self.balance == other.balance
            return NotImplemented

        def __lt__(self, other):
            if isinstance(other, BankAccount):
                return self.balance < other.balance
            return NotImplemented

It'd be nice to be able to eliminate an import and have the lines of
code and instead write that as:

    class BankAccount:
        def __init__(self, balance):
            self.balance = balance

        def __sort_key__(self):
            return self.balance


I would expect these two to give the same behavior: instances of
BankAccount should still be fully comparable and sortable, with all of
these operations effectively being deferred to comparisons and sorts of
the sort key.

Now for the cases against:

1. I made one important decision explicitly (twice, unfortunately) in
the first code block that disappeared in the second: what "other"
instances should be considered comparable to instances of BankAccount?
Should it be decided structurally, like in the documentation example for
`functools.total_ordering`? Should it be "any subclass of BankAccount"?
Or maybe it should only be instances of BankAccount itself, not
subclasses? (We just went around on this very question for PEP 557,
dataclasses.) If Python added __sort_key__, it would have to just pick a
behavior here, which would be unfortunate for cases where that behavior
is wrong. Or maybe we could also add a __sort_allowed__ method...

2. There might actually be a performance cost here, since this wouldn't
replace the existing rich comparison dunder methods, so it would add one
more thing Python has to check when trying to compare two objects.

Carl

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20171203/2dccb436/attachment.sig>


More information about the Python-ideas mailing list