4 Stimmen

Was macht python3 mit den Methoden, die dem Argument "key" von sorted() übergeben werden?

Ich habe eine Frage dazu, wie Python die an sorted() übergebenen Methoden behandelt. Betrachten Sie das folgende kleine Skript:

#!/usr/bin/env python3

import random

class SortClass:
    def __init__(self):
        self.x = random.choice(range(10))
        self.y = random.choice(range(10))
    def getX(self):
        return self.x
    def getY(self):
        return self.y

if __name__ == "__main__":
    sortList = [SortClass() for i in range(10)]
    sortedList = sorted(sortList, key = SortClass.getX)
    for object in sortedList:
        print("X:", object.getX(),"Y:",object.getY())

Dies ergibt eine ähnliche Ausgabe wie die folgende:

X: 1 Y: 5
X: 1 Y: 6
X: 1 Y: 5
X: 2 Y: 8
X: 2 Y: 1
X: 3 Y: 6
X: 4 Y: 2
X: 5 Y: 4
X: 6 Y: 2
X: 8 Y: 0

Dieses Skript sortiert die SortClass-Objekte nach dem Wert des x-Feldes der einzelnen Instanzen. Beachten Sie jedoch, dass das Argument "key" von sorted auf SortClass.getX verweist, nicht auf eine bestimmte Instanz von SortClass. Ich bin etwas verwirrt darüber, wie Python die als "key" übergebene Methode tatsächlich verwendet. Funktioniert der Aufruf von getX() auf diese Weise, weil die übergebenen Objekte vom gleichen Typ sind wie das Argument "self"? Ist dies eine sichere Verwendung des Arguments "Schlüssel"?

8voto

Benjamin Peterson Punkte 16442

Methoden in Klassen sind nur Funktionen.

class MyClass(object):
...     def my_method(self): pass
...
>>> MyClass.my_method
<function my_method at 0x661c38>

Wenn Sie eine Methode aus einer Instanz einer Klasse abrufen, verwendet Python einige magische Mittel (Deskriptoren genannt), um eine gebundene Methode zurückzugeben. Gebundene Methoden fügen automatisch die Instanz als erstes Argument ein, wenn sie aufgerufen werden.

>>> MyClass().my_method
<bound method MyClass.my_method of <__main__.myClass object at 0x6e2498>>

Wie Sie jedoch festgestellt haben, können Sie die Funktion auch direkt mit einer Instanz als erstem Argument aufrufen: MyClass.my_method(MyClass())

Genau das passiert mit sorted() . Python ruft die Funktion SortedClass.getx mit dem Element in der Liste auf, das zufällig eine Instanz von SortedClass ist.

(Übrigens gibt es bessere Möglichkeiten, das zu tun, was Sie gerade tun. Zunächst einmal sollten Sie keine Methoden verwenden, um Attribute freizulegen wie getX . Verwenden Sie Eigenschaften oder einfache Attribute. Beachten Sie auch operator.itemgetter y operator.methodcaller .)

0voto

Raymond Hettinger Punkte 197261

+1 für die Antwort von Benjamin.

Lesen Sie auch das HowTo Sortieren, wenn Sie das Sortieren in Python beherrschen wollen: http://docs.python.org/howto/sorting.html

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X