Одной из менее известных, но ценных функций Python является возможность реализации магических методов на объектах. Используя волшебные методы, мы можем написать более чистый код, интуитивно понятный и простой для понимания.
С помощью magic methods мы можем создавать интерфейсы для взаимодействия с объектами таким образом, чтобы они казались более питоновскими. В этой статье вы познакомитесь с магическими методами, обсудите лучшие практики их создания и изучите распространенные магические методы, с которыми вы столкнетесь.
Что такое магические методы?
Магические методы - это методы Python, которые определяют, как ведут себя объекты Python при выполнении над ними обычных операций. Эти методы четко определены с помощью двойного подчеркивания до и после имени метода.
В результате их обычно называют методами дандера, как в double подоценкой. Распространенный метод dunder, с которым вы, возможно, уже сталкивались, - это __init__() метод, который используется для определения конструкторов классов.
Как правило, методы dunder не предназначены для вызова непосредственно в вашем коде; скорее, они будут вызываться интерпретатором во время выполнения программы.
Почему магические методы полезны?
Магические методы являются полезной концепцией в объектно-ориентированном программировании на Python. Используя их, вы указываете поведение ваших пользовательских типов данных, когда они используются с обычными встроенными операциями. Эти операции включают:
🟢 Арифметические операции
🟢 Операции сравнения
🟢 Операции жизненного цикла
🟢 Операции представления
В следующем разделе будет обсуждаться, как реализовать магические методы, которые определяют поведение приложения при использовании во всех вышеуказанных категориях.
Как определить магические методы
Как упоминалось ранее, магические методы определяют поведение объектов. Как таковые, они определены как часть класса объекта. Поскольку они являются частью класса object, они принимают в качестве первого аргумента self, который является ссылкой на сам объект.
Они могут принимать дополнительные аргументы в зависимости от того, как они будут вызваны интерпретатором. Они также четко определены двумя символами подчеркивания перед и после их названий.
Реализация
Многое из того, что мы обсуждали до сих пор, кажется теоретическим и абстрактным. В этом разделе мы реализуем простой класс Rectangle.
Этот класс будет иметь свойства длины и ширины. Используя метод __init__, вы можете указать эти свойства при создании экземпляра. Кроме того, вы сможете сравнить разные прямоугольники, чтобы увидеть, равен ли он, меньше или больше другого, используя операторы ==, < и >. Наконец, прямоугольник должен быть способен обеспечивать осмысленное строковое представление.
Настройка среды программирования
Чтобы следовать этому пошаговому руководству, вам понадобится среда выполнения Python. Вы можете использовать Visual Studio Code.
Создание класса Rectangle
Во-первых, давайте начнем с определения класса Rectangle.
class Rectangle:
pass
Создание метода конструктора
Далее давайте создадим наш первый магический метод, метод конструктора класса. Этот метод примет высоту и ширину и сохранит их как атрибуты в экземпляре класса.
class Rectangle:
def __init__(self, height, width):
self.height = height
self.width = width
Создание магического метода для представления строк
Далее мы хотим создать метод, который позволяет нашему классу генерировать удобочитаемую строку для представления объекта. Этот метод будет вызываться всякий раз, когда мы вызываем str() функцию, передающую экземпляр Rectangle класса в качестве аргумента. Этот метод также будет вызываться при вызове функций, которые ожидают строковый аргумент, таких как print функция.
class Rectangle:
def __init__(self, height, width):
self.height = height
self.width = width
def __str__(self):
return f'Rectangle({self.height}, {self.width})'
__str__() Метод должен возвращать строку, которой вы хотели бы представить объект. В этом случае мы возвращаем строку формата Rectangle(<height>, <width>), где высота и ширина - это сохраненные размеры прямоугольника.
Создание магических методов для операций сравнения
Далее мы хотим создать операторы сравнения для операций равно, меньше и больше, чем. Это называется перегрузкой оператора. Для их создания мы используем магические методы __eq__, __lt__ и __gt__ соответственно. Эти методы вернут логическое значение после сравнения площадей прямоугольников.
class Rectangle:
def __init__(self, height, width):
self.height = height
self.width = width
def __str__(self):
return f'Rectangle({self.height}, {self.width})'
def __eq__(self, other):
""" Checking for equality """
return self.height * self.width == other.height * other.width
def __lt__(self, other):
""" Checking if the rectangle is less than the other one """
return self.height * self.width < other.height * other.width
def __gt__(self, other):
""" Checking if the rectage is greater than the other one """
return self.height * self.width > other.height * other.width
Как вы можете видеть, эти методы принимают два параметра. Первый - это текущий прямоугольник, а второй - другое значение, с которым он сравнивается. Это значение может быть другим экземпляром Rectangle или любым другим значением. Логика того, как сравнение и условия, при которых сравнение вернет true, полностью зависят от вас.
Общие магические методы
В следующем разделе мы обсудим распространенные магические методы, с которыми вы столкнетесь и будете использовать.
#1. Арифметические операции
Арифметические магические методы вызываются, когда экземпляр вашего класса помещается слева от арифметического знака. Метод будет вызван с двумя аргументами, первый из которых является ссылкой на экземпляр. Второе значение - это объект справа от знака. Методы и знаки следующие:
#2. Операции сравнения
Подобно арифметическим магическим методам, эти методы вызываются, когда экземпляр класса, для которого они определены, помещается слева от оператора сравнения. Также, как и арифметические магические методы, они вызываются с двумя параметрами; первый - это ссылка на экземпляр объекта. Второй - это ссылка на значение в правой части знака.
#3. Операции жизненного цикла
Эти методы будут вызываться в ответ на различные методы жизненного цикла объекта, такие как создание экземпляра или удаление. Конструктор __init__ подпадает под эту категорию. Распространенные методы в этой категории перечислены в таблице ниже:
#4. Операции представления
Рекомендации по созданию магических методов
Волшебные методы клёвые они упростят ваш код. Однако при их использовании важно помнить о следующих вещах.
- Используйте их экономно – реализация слишком большого количества магических методов в ваших классах затрудняет понимание вашего кода. Ограничьтесь реализацией только основных.
- Убедитесь, что вы понимаете влияние на производительность таких методов, как __setatrr__ и __getattr__, прежде чем использовать их.
- Документируйте поведение ваших магических методов, чтобы другие разработчики могли точно знать, что они делают. Это упрощает их использование и отладку при необходимости.
Заключительные слова
В этой статье я представил магические методы как способ создания классов, которые можно использовать со встроенными операциями. Я также обсудил, как они определяются, и рассмотрел пример класса, в котором реализованы магические методы. Далее я упомянул различные методы. Если у Вас есть какое то дополнение к тому что я упустил, будет интересно почитать в Ваших комментариях.