Python: wie funktioniert die functools cmp_to_key-Funktion funktioniert?

In Python, die beide list.sort Methode und sorted built-in-Funktion akzeptiert einen optionalen parameter namens key, das ist eine Funktion, die, gegeben ein element aus der Liste gibt die Sortier-Schlüssel.

Älteren Python-Versionen verwendet einen anderen Ansatz mit Hilfe cmp parameter statt, ist das eine Funktion, die, gegeben zwei Elemente aus der Liste gibt eine negative Zahl, wenn der erste kleiner als das zweite, null wenn es sind gleich, und eine positive Zahl, wenn die erste größer ist. An einem gewissen Punkt, dieser parameter wurde als veraltet markiert und war nicht enthalten in Python 3.

Den anderen Tag wollte ich zum Sortieren einer Liste von Elementen in einer Weise, dass ein cmp Funktion war sehr viel leichter zu schreiben als ein key ein. Ich wollte nicht zu verwenden, eine als veraltet markierte Funktion, so dass ich die Dokumentation gelesen und ich fand, dass es eine funtion namens cmp_to_key im functools Modul, das, wie sein name schon sagt, erhält ein cmp Funktion und gibt einen key einen... oder das, was ich dachte, bis ich Lesen Sie den source-code (oder zumindest eine gleichwertige version) dieses high-level Funktion im docs

def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K(object):
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K

Trotz der Tatsache, dass cmp_to_key wie erwartet funktioniert, bekomme ich von der Tatsache überrascht, dass diese Funktion nicht wieder eine Funktion, aber eine K Klasse statt. Warum? Wie funktioniert es? Meine Vermutung ist es, dass die sorted Funktion, die intern prüft, ob die cmp ist eine Funktion oder eine Klasse K oder etwas ähnliches, aber ich bin mir nicht sicher.

P. S.: Trotz dieser Seltsamkeit, fand ich, dass die K-Klasse ist sehr nützlich. Überprüfen Sie diesen code:

from functools import cmp_to_key

def my_cmp(a, b):
    # some sorting comparison which is hard to express using a key function

class MyClass(cmp_to_key(my_cmp)):
    ...

Diese Weise eine Liste von Instanzen von MyClass werden können, standardmäßig sortiert nach den definierten Kriterien in my_cmp

Schreibe einen Kommentar