我有一个关于python如何处理传递给sorted()的方法的问题。请考虑以下小脚本:
#!/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对象进行排序。但是请注意,排序的“key”参数指向SortClass.getX,而不是指向SortClass的任何特定实例。我对python如何实际使用传递为“key”的方法感到困惑。调用像这样的getX()是否有效,因为传递给它的对象与“self”参数的类型相同?这是“关键”论证的安全用法吗?
答案 0 :(得分: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
这样的属性。使用属性或普通属性。另外,看看{{ 1}}和operator.itemgetter
。)
答案 1 :(得分:0)
本杰明的答案+1。
另外,如果你想在Python中掌握排序,请阅读Sorting HowTo:http://docs.python.org/howto/sorting.html