2009-04-21 2 views
4

Ich habe eine Frage darüber, wie Python die an sorted() übergebenen Methoden behandelt. Betrachten Sie das folgende kleine Skript:Was macht python3 mit den Methoden, die an das Argument "key" von sorted() übergeben werden?

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 der jeweiligen x Feldes Beispiel:

#!/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()) 

Welche Ausgabe ähnlich der folgenden gibt. Beachten Sie jedoch, dass das Argument "key" von sorted auf SortClass.getX verweist, nicht auf eine bestimmte Instanz von SortClass. Ich bin ein wenig verwirrt darüber, wie Python tatsächlich die als "Schlüssel" übergebene Methode verwendet. Kann getX() so aufgerufen werden, weil die übergebenen Objekte vom selben Typ sind wie das Argument "self"? Ist dies eine sichere Verwendung des Arguments "Schlüssel"?

+1

Beachten Sie, dass Getter und Setter unpythonic sind. Sie sollten dies stattdessen mit operator.attrgetter schreiben. Beispiel hier: http://dpaste.com/hold/36126/ – nosklo

+0

Ich denke du meinst: 'sortList = [SortClass() für i in Bereich (10)]' –

Antwort

8

Methoden auf 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 holen, verwendet Python etwas Magie (Deskriptoren genannt) eine gebundene Methode zurückzukehren. Gebundene Methoden fügen die Instanz automatisch als erstes Argument ein, wenn sie aufgerufen werden.

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

Doch wie Sie bemerkt haben, können Sie auch die Funktion mit einer Instanz als erstes Argument direkt aufrufen: MyClass.my_method(MyClass())

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

(By the way, gibt es bessere Möglichkeiten zu tun, was Sie tun. Erstens, keine Methoden verwenden, um Attribute wie getX zu belichten. Verwenden Sie Eigenschaften oder einfache Attribute. Auch sehen operator.itemgetter und operator.methodcaller.)

Verwandte Themen