Что такое функтор в Python

Ответ

Функтор (или вызываемый объект, callable object) в Python — это любой объект, у которого реализован магический метод __call__(). Это позволяет использовать экземпляр класса так, как если бы он был обычной функцией.

Основное преимущество функторов — возможность сохранять состояние между вызовами.

Пример:

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

class Counter:
    def __init__(self):
        self.count = 0
        print("Счетчик инициализирован")

    def __call__(self, *args, **kwargs):
        # Этот метод выполняется при вызове экземпляра как функции
        self.count += 1
        print(f"Вызов номер {self.count}")

# Создаем экземпляр класса
my_counter = Counter()

# Используем экземпляр как функцию
my_counter() # Выведет: Вызов номер 1
my_counter() # Выведет: Вызов номер 2
my_counter() # Выведет: Вызов номер 3

Ключевые преимущества:

  • Состояние: Функтор — это объект, он может хранить данные в своих атрибутах (self.count) между вызовами.
  • Гибкость: Помимо __call__, класс может иметь и другие методы для настройки или получения данных.
  • Чистый синтаксис: Код my_counter() выглядит более естественно, чем, например, my_counter.execute().

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

Ответ 18+ 🔞

О, слушай, вот тебе про функторы в Питоне, а то я тут вспомнил одну историю, блядь, про моего кореша, который пытался сделать счётчик на глобальной переменной и потом охуел, когда всё накрылось медным тазом. Так вот, функтор — это, по сути, любой объект, который можно хуякнуть как функцию, потому что у него есть магический метод __call__(). Всё просто, ёпта.

Главный прикол, блядь, в чём? В том, что этот ушлёпок может сохранять своё состояние между вызовами. То есть он не тупо отработал и забыл, как обычная функция, а помнит, что с ним делали, сука. Это как тот самый чувак, который всё записывает в блокнотик, а потом при встрече тебе припоминает.

Смотри, вот пример, пиздец какой простой:

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

class Counter:
    def __init__(self):
        self.count = 0
        print("Счетчик инициализирован, готов к работе, блядь")

    def __call__(self, *args, **kwargs):
        # Вот эта хуйня срабатывает, когда экземпляр вызывают как функцию
        self.count += 1
        print(f"Вызов номер {self.count}, ёпта")

# Создаём экземпляр, вот этого самого счётчика
my_counter = Counter()

# А теперь просто хуячим его как функцию, и он всё помнит!
my_counter() # Напишет: Вызов номер 1, ёпта
my_counter() # Напишет: Вызов номер 2, ёпта
my_counter() # Напишет: Вызов номер 3, ёпта

В чём же, блядь, соль, спросишь ты?

  • Состояние, ёпта: Это же объект, сука! Он может хранить в своих полях (типа self.count) любую хуйню между вызовами. Не то что эти одноразовые функции.
  • Гибкость, блядь: Помимо самого __call__, в этот класс можно напихать ещё кучу других методов. Настроить, переконфигурировать — да хоть танцевать с бубном.
  • Красивый синтаксис, в рот меня чих-пых: Код my_counter() выглядит куда приятнее, чем какое-нибудь my_counter.invoke_and_increment_for_fuck_sake(). Чисто, понятно, без лишней писанины.

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