Почему у нас есть вызываемые объекты в Python? - PullRequest
11 голосов
/ 13 марта 2010

Какова цель вызываемого объекта? Какие проблемы они решают?

Ответы [ 3 ]

13 голосов
/ 13 марта 2010

Многие виды объектов могут вызываться в Python, и они могут служить многим целям:

  • функции могут вызываться, и они могут нести «замыкание» из внешней функции
  • классы могут быть вызваны, и вызов класса дает вам экземпляр этого класса
  • методы могут вызываться для функционально-подобного поведения, конкретно относящегося к экземпляру
  • статические методы и методы классов могут вызываться для функциональных функций, когда функциональность относится к «целому классу» в некотором смысле (полезность статических методов сомнительно, так как метод класса мог бы сделать то же самое; -)
  • генераторы могут быть вызваны, и при вызове генератора вы получаете объект итератора
  • наконец, и это может быть именно то, о чем вы спрашивали (не осознавая этого все вышеперечисленное тоже является объектом ... !!!), вы можете закодировать класс с экземплярами вызываемый: это часто самый простой способ иметь вызовы, которые обновляют экземпляр состояние, а также зависит от него (хотя функция с подходящим замыканием и метод, предлагать альтернативы, вызываемый экземпляр - это единственный путь, когда вам нужно выполнить оба вызова и для некоторых других конкретных операций с одним и тем же объектом: для Например, объект, который вы хотите иметь возможность вызывать, но также применять индексирование, чтобы лучше быть экземпляром класса, который можно вызывать и индексировать; -).

Широкий спектр примеров "проблем, которые они решают" предлагается стандартной библиотекой Python, в которой есть много случаев каждого из конкретных типов, которые я упоминал выше.

9 голосов
/ 13 марта 2010

Они принимают параметры и возвращают результат в зависимости от этих параметров.

A callable - это просто абстрактная форма функции или интерфейса, который определяет, что объект действует как функция (т.е. принимает параметры).

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

Одна идея, почему использовать такое - иметь какой-то фабричный объект, который сам создает другие объекты.

2 голосов
/ 13 марта 2010

Существуют области, особенно в «функциях, вызывающих функции функций», где объекты позволяют меньше вложенности.

Рассмотрите возможность создания классического декоратора, который проверяет уровень авторизации перед вызовом функции. С помощью понятно:

@check_authorization(level="Manager")
def update_price(Item, new_price):...

Вы можете сделать это как вложенные функции:

def check_authorization(level):
     def take_params(function):
         def concrete(*args, **kwargs):
             if user_level_greater_than(level):
                 return function(*args, 
                     **kwargs)
             return None
         return concrete
     return take_params

Или вы можете сделать это как класс, что может быть понятнее:

  class check_authorization(object):
      def __init__(level):
         self.level = level
      def __call__(function):
          self.function = function
          return self.dec
      def dec(self, *args, **kwargs):
          if user_level_greater_than(self.level):
             return self.function(*args,v**kwargs)
          return None

Многие сочтут этот плоский метод более понятным. Конечно, я верю в обман, потому что мне нравятся правильные подписи и метаданные:

from dectools.dectools import make_call_if

@make_call_if
def check_authorization(function, arg, kwargs, level):
    return user_level_greater_than(level)

Вызываемый объект - это инструмент, который подходит для некоторых известных приложений, а также может быть полезен для странной проблемы, которую бросает вам реальная жизнь.

...