Понимание __call__ и list.sort (ключ) - PullRequest
5 голосов
/ 27 октября 2010

У меня есть следующий код, который я пытаюсь понять:

>>> class DistanceFrom(object):
        def __init__(self, origin):
            self.origin = origin
        def __call__(self, x):
            return abs(x - self.origin)  

>>> nums = [1, 37, 42, 101, 13, 9, -20]
>>> nums.sort(key=DistanceFrom(10))
>>> nums
[9, 13, 1, 37, -20, 42, 101]

Может кто-нибудь объяснить, как это работает? Насколько я понял, __call__ - это то, что вызывается при вызове object(), вызывая объект как функцию.

Что я не понимаю, так это nums.sort(key=DistanceFrom(10)). Как это работает? Может кто-нибудь, пожалуйста, объясните эту строку?

Спасибо!

Ответы [ 5 ]

8 голосов
/ 27 октября 2010

__call__ в python позволяет классу запускаться так, как будто это функция.Вы можете попробовать это вручную:

>>> dis = DistanceFrom(10)
>>> print dis(10), dis(5), dis(0)
0 5 10
>>> 

Что делает сортировка, это вызывает эту функцию для каждого элемента в вашем списке и использует возвращенное значение в качестве ключа сортировки.В этом примере вы получите список с элементами, ближайшими к 10, а затем еще ближе к концу.

7 голосов
/ 27 октября 2010

Здесь я определил функцию DistanceFrom(), которая может использоваться аналогично вашему классу, но может быть проще следовать

>>> def DistanceFrom(origin):
...     def f(x):
...         retval = abs(x - origin)
...         print "f(%s) = %s"%(x, retval)
...         return retval
...     return f
... 
>>> nums = [1, 37, 42, 101, 13, 9, -20]
>>> nums.sort(key=DistanceFrom(10))
f(1) = 9
f(37) = 27
f(42) = 32
f(101) = 91
f(13) = 3
f(9) = 1
f(-20) = 30
>>> nums
[9, 13, 1, 37, -20, 42, 101]

Итак, вы видите, что объект возвращается DistanceFrom вызывается один раз для каждого элемента nums, а затем возвращается nums, отсортированный в соответствии с возвращенными значениями

4 голосов
/ 27 октября 2010

Сортирует список nums на месте с использованием key функционального объекта DistanceFrom(10).Он должен вызываться, потому что key должен вызываться.Полученный результат сортируется по их «удаленности» от 10, то есть 9 - самое близкое значение к 10, 101 - самое дальнее.

После инициализации объекта и передачи в качестве параметра key вsort метод, на каждой итерации он будет вызываться с текущим значением (вот что такое x), а возвращаемое значение будет использоваться для определения позиции x в результирующем списке.

1 голос
/ 27 октября 2010

Документы на Python довольно хороши, когда я обнаруживаю, что не понимаю основ. Я нашел их с помощью Google.

Параметр key - это функция, которая сортирует вызов элементов списка. Я нашел этот документ, найдя в Google sort site:http://docs.python.org/ и затем поискав key=.

__call__ - это функция, которую вы можете добавить к объекту, чтобы сделать этот объект вызываемым, как если бы он был функцией. Я нашел этот документ, погуглив __call__ site:http://docs.python.org/ и затем перейдя по ссылке на документ для __call__.

1 голос
/ 27 октября 2010

Когда вы вызываете что-то, это означает, что вы ожидаете, что оно вернет значение. Когда вы создаете класс, для которого определен метод __call__, вы указываете, что экземпляр этого класса может вести себя как функция.

Для целей этого вопроса это:

class DistanceFrom(object):
        def __init__(self, origin):
            self.origin = origin
        def __call__(self, x):
            return abs(x - self.origin) 

Функционально эквивалентно:

def distance_from(origin, other):
    return abs(other - origin)

Что касается аргумента key для сортировки, вот ваше объяснение прямо из документации Python:

клавиша определяет функцию одного Аргумент, который используется для извлечения ключ сравнения из каждого элемента списка: key=str.lower. Значением по умолчанию является Нет (сравните элементы напрямую)

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