Что делает python3 с методами, передаваемыми аргументу "key" в sorted ()? - PullRequest
4 голосов
/ 21 апреля 2009

У меня есть вопрос о том, как 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

Этот скрипт сортирует объекты SortClass в соответствии со значением поля x каждого экземпляра. Однако обратите внимание, что аргумент «key» отсортированных указывает на SortClass.getX, а не на какой-либо конкретный экземпляр SortClass. Я немного сбит с толку относительно того, как Python фактически использует метод, переданный как «ключ». Вызывает ли вызов getX () такую ​​работу, потому что переданные ему объекты того же типа, что и аргумент "self"? Безопасно ли использовать аргумент «ключ»?

Ответы [ 2 ]

8 голосов
/ 21 апреля 2009

Методы на классах - это просто функции.

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.itemgetter operator.methodcaller.)

0 голосов
/ 18 октября 2011

+ 1 за ответ Бенджамина.

Кроме того, прочитайте инструкции по сортировке, если вы хотите освоить сортировку в Python: http://docs.python.org/howto/sorting.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...