2009-04-21 55 views
4

我有一個關於python如何處理傳遞給sorted()的方法的問題。請看下面的小腳本:python3對傳遞給sorted()的「key」參數的方法做了什麼?

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

其中給出類似以下的輸出:

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 

這個腳本根據每個實例的X字段的值排序SortClass對象。但是,請注意,排序的「鍵」參數指向SortClass.getX,而不是SortClass的任何特定實例。我有點困惑,因爲python實際上如何使用作爲「key」傳遞的方法。像這樣調用getX()是否工作,因爲傳遞給它的對象與「self」參數的類型相同?這是對「關鍵」參數的安全使用嗎?

+1

注意getter和setter方法是unpythonic。你應該用operator.attrgetter來寫這個。示例:http://dpaste.com/hold/36126/ – nosklo 2009-04-21 03:44:14

回答

8

類的方法只是函數。

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

當您從某個類的實例中獲取方法時,Python會使用一些魔術(稱爲描述符)來返回一個綁定方法。綁定方法在被調用時自動插入實例作爲第一個參數。

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

然而,正如你已經注意到了,你也可以直接調用該函數以一個實例作爲第一個參數:MyClass.my_method(MyClass())

這與sorted()什麼事情。 Python使用列表中的項目調用函數SortedClass.getx,該項目正好是SortedClass的一個實例。

(順便說一下,有更好的方法做,你在做什麼,所有的。首先,不使用方法暴露屬性,如getX。使用性質或純屬性。另外,看operator.itemgetteroperator.methodcaller。)