Как использовать python __call__ в Python?
Метод call() в Python: Создание вызываемых объектов
Введение
В Python вызываемым объектом называется любой объект, который можно вызвать с помощью пары скобок и, при необходимости, передать ряд аргументов. Функции, классы и методы - все они являются примерами вызываемых объектов в Python. Кроме того, вы также можете создавать специальные классы, которые создают вызываемые экземпляры. Для этого вы можете добавить специальный метод .call() в свой класс.
Экземпляры класса с методом .__call__()
ведут себя как функции, предоставляя гибкий и удобный способ добавления функциональности в ваши объекты. Понимание того, как создавать и использовать вызываемые экземпляры, является ценным навыком для вас как разработчика Python.
В этом руководстве вы:
- Поймете концепцию вызываемых объектов в Python
- Создадите вызываемые экземпляры, предоставив вашим классам метод
.__call__()
- Поймете разницу между
.__init__()
и.__call__()
- Напишите несколько примеров использования вызываемых экземпляров для решения реальных проблем.
Понимание вызываемых объектов в Python
В Python вызываемым объектом называется любой объект, который можно вызвать с помощью пары скобок и ряда аргументов, если это необходимо. Вы сталкиваетесь с различными примерами вызываемых объектов в ежедневном взаимодействии с Python. Некоторые из них:
- Встроенные функции и классы
- Экземпляры классов, которые реализуют метод
.__call__()
Давайте подробнее рассмотрим вызываемые экземпляры и их использование в Python.
Создание вызываемых экземпляров с помощью метода .call()
Вызываемые экземпляры класса полезны тем, что они позволяют создавать объекты, которые можно вызывать как функции. Для создания вызываемых экземпляров вы должны добавить метод . __call__()
в свой класс.
Давайте представим, что у нас есть класс Multiplier
, который умножает число на указанное значение:
В этом примере мы создали класс Multiplier
, в конструкторе которого мы сохраняем значение factor
в атрибуте экземпляра с тем же именем. Затем мы определяем метод .__call__()
, который принимает число и выполняет умножение. Когда мы создаем экземпляр класса и вызываем его с аргументом, он работает как функция и возвращает результат умножения.
Позвольте рассмотреть некоторые расширенные примеры использования метода . __call__()
в Python.
Применение метода .call() в Python
Состояние вызываемых объектов
Вызываемые объекты могут быть полезными, когда вам нужно сохранять состояние между вызовами. Допустим, у нас есть класс Counter
, который подсчитывает количество вызовов:
В этом примере класс Counter
имеет атрибут count
, который инициализируется нулем в конструкторе. Метод .__call__()
увеличивает значение атрибута count
на 1 и возвращает его после каждого вызова объекта counter
. Таким образом, мы можем использовать вызываемый экземпляр класса Counter
, чтобы отслеживать количество вызовов.
Кэширование вычисленных значений
Вызываемые объекты также могут использоваться для кэширования вычисленных значений. Например, у вас может быть класс Fibonacci
, который вычисляет числа Фибоначчи:
В этом примере класс Fibonacci
содержит атрибут cache
, в котором мы кэшируем вычисленные значения чисел Фибоначчи. Метод .__call__()
проверяет, есть ли значение в кэше, и если его нет, он рекурсивно вызывает себя для предыдущих чисел Фибоначчи и сохраняет результат. Таким образом, мы можем использовать вызываемый экземпляр класса Fibonacci
, чтобы быстро получить значения последовательности чисел Фибоначчи.
Создание понятных и удобных API
Вызываемые экземпляры также могут использоваться для создания понятных и удобных API. Например, у вас может быть класс EmailSender
, который отправляет электронные письма:
В этом примере класс EmailSender
принимает адрес электронной почты отправителя в конструкторе. Метод .__call__()
принимает адрес электронной почты получателя, тему и тело письма. Здесь мы можем использовать вызываемый экземпляр класса EmailSender
, чтобы легко отправлять электронные письма с заданными параметрами.
Расширенное использование метода .call()
Создание декораторов на основе классов
Метод . __call__()
также может быть использован для создания декораторов на основе классов. Декораторы позволяют динамически изменять поведение функций или методов. Давайте рассмотрим пример декоратора, который измеряет время выполнения функции:
В этом примере класс Timer
принимает декорируемую функцию в конструкторе. Мы определяем метод .__call__()
, который засекает время перед вызовом функции, выполняет ее и замеряет время выполнения. Затем мы создаем экземпляр класса Timer
с помощью декоратора @Timer
перед объявлением функции expensive_function
. Когда мы вызываем expensive_function
, она оборачивается вызываемым экземпляром Timer
, который измеряет время выполнения и выводит его на экран.
Реализация шаблона проектирования “Стратегия”
Метод . __call__()
также может быть использован для реализации шаблона проектирования “Стратегия”. Шаблон “Стратегия” позволяет определить семейство алгоритмов, инкапсулировать каждый из них и делать их взаимозаменяемыми. Давайте рассмотрим пример, где мы используем вызываемые экземпляры для реализации “Стратегии” расчета скидки:
В этом примере класс DiscountStrategy
принимает коэффициент скидки в конструкторе. Метод .__call__()
принимает исходную цену и применяет скидку, возвращая цену со скидкой. Мы создаем два экземпляра класса DiscountStrategy
с разными коэффициентами скидки и вызываем каждый экземпляр с исходной ценой для расчета цены со скидкой.
Заключение
Вызываемые экземпляры в Python предоставляют гибкий и удобный способ добавления функциональности в ваши объекты. В этом руководстве вы изучили, как создавать и использовать вызываемые экземпляры, предоставляя вашим классам метод . __call__()
.
Вы познакомились с различными примерами использования вызываемых экземпляров, такими как сохранение состояния между вызовами, кэширование вычисленных значений, создание понятных и удобных API, создание декораторов на основе классов и реализация шаблона проектирования “Стратегия”. Эти примеры показывают, как вызываемые экземпляры могут быть полезными в решении реальных проблем и улучшении вашего опыта в Python.
Теперь, когда вы освоили метод . __call__()
в Python, вы можете применить свои новые знания для создания более гибких и мощных классов в своих проектах. Удачи в вашем путешествии в мир Python!