4

我有一个关于 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 对象进行排序。但是请注意,sorted 的“key”参数指向 SortClass.getX,而不是任何特定的 SortClass 实例。我对python如何实际使用作为“键”传递的方法有点困惑。像这样调用 getX() 是否有效,因为传递给它的对象与“self”参数的类型相同?这是对“关键”参数的安全使用吗?

4

2 回答 2

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。)

于 2009-04-21T02:55:17.103 回答
0

+1为本杰明的回答。

此外,如果您想掌握 Python 中的排序,请阅读 Sorting HowTo:http: //docs.python.org/howto/sorting.html

于 2011-10-18T17:02:04.903 回答