Що таке магічні методи в Python і як ними користуватися

Однією з менш відомих, але цінних можливостей Python є можливість реалізації магічних методів на об’єктах. Використовуючи чарівні методи, ми можемо написати чистіший код, інтуїтивно зрозумілий і простий для розуміння.

За допомогою магічних методів ми можемо створювати інтерфейси для взаємодії з об’єктами у спосіб, який виглядає більш Pythonic. Ця стаття познайомить вас із магічними методами, обговорить найкращі методи їх створення та дослідить поширені магічні методи, з якими ви зіткнетеся.

Що таке магічні методи?

Чарівні методи — це методи Python, які визначають поведінку об’єктів Python, коли над ними виконуються стандартні операції. Ці методи чітко визначені подвійним підкресленням перед і після назви методу.

У результаті їх зазвичай називають методами dunder, як подвійне підкреслення. Поширеним методом dunder, з яким ви, можливо, вже стикалися, є метод __init__(), який використовується для визначення конструкторів класів.

Як правило, методи dunder не призначені для виклику безпосередньо у вашому коді; швидше, вони будуть викликані інтерпретатором під час виконання програми.

Чому магічні методи корисні?

Чарівні методи є корисною концепцією в об’єктно-орієнтованому програмуванні на Python. Використовуючи їх, ви вказуєте поведінку ваших користувальницьких типів даних, коли вони використовуються зі звичайними вбудованими операціями. Ці операції включають:

🟢 Арифметичні дії

🟢 Операції порівняння

🟢 Операції життєвого циклу

🟢 Представницька діяльність

У наступному розділі буде обговорено, як реалізувати чарівні методи, які визначають поведінку програми під час використання в усіх вищевказаних категоріях.

Як визначити магічні методи

Як згадувалося раніше, магічні методи визначають поведінку об’єктів. Таким чином, вони визначені як частина класу об’єкта. Оскільки вони є частиною класу об’єктів, вони приймають як перший аргумент self, який є посиланням на сам об’єкт.

Вони можуть приймати додаткові аргументи в залежності від того, як їх буде викликати перекладач. Вони також чітко визначені двома підкресленнями перед і після їх імен.

  Контрольний список кібербезпеки для малого та середнього бізнесу

Реалізація

Багато з того, що ми обговорювали досі, здається теоретичним і абстрактним. У цьому розділі ми реалізуємо простий клас Rectangle.

Цей клас матиме властивості length і width. Використовуючи метод __init__, ви можете вказати ці властивості під час створення екземпляра. Крім того, ви зможете порівнювати різні прямокутники, щоб побачити, чи вони дорівнюють, менше чи більше іншого за допомогою операторів ==, < і >. Нарешті, прямокутник повинен бути здатний забезпечувати значуще представлення рядків.

Налаштування середовища кодування

Щоб виконати цю інструкцію, вам знадобиться середовище виконання Python. Ви можете використовувати локальний компілятор або онлайн-компілятор techukraine.net Python.

Створення класу Rectangle

Спочатку давайте почнемо з визначення класу Rectangle.

class Rectangle:
    pass

Створення методу конструктора

Далі створимо наш перший магічний метод, метод конструктора класу. Цей метод візьме висоту та ширину та збереже їх як атрибути екземпляра класу.

class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width

Створення магічного методу для представлення рядків

Далі ми хочемо створити метод, який дозволить нашому класу генерувати зрозумілий людині рядок для представлення об’єкта. Цей метод буде викликаний щоразу, коли ми викликаємо функцію str(), передаючи екземпляр класу Rectangle як аргумент. Цей метод також буде викликано, коли ви викликаєте функції, які очікують рядковий аргумент, наприклад функцію друку.

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(, ), де висота та ширина є збереженими розмірами прямокутника.

Створення магічних методів для операцій порівняння

Далі ми хочемо створити оператори порівняння для операцій дорівнює, менше та більше. Це називається перевантаженням оператора. Для їх створення ми використовуємо магічні методи __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 або будь-яким іншим значенням. Логіка порівняння та умови, за яких порівняння повертатиме істину, повністю залежать від вас.

  8 попереджувальних ознак, що на вашому Mac можуть виникнути проблеми (і як це виправити)

Поширені магічні методи

У цьому наступному розділі ми обговоримо загальні магічні методи, з якими ви зіткнетеся та використаєте.

#1. Арифметичні операції

Арифметичні магічні методи викликаються, коли екземпляр вашого класу розміщується ліворуч від арифметичного знака. Метод буде викликано з двома аргументами, перший з яких буде посиланням на екземпляр. Друге значення – об’єкт праворуч від знака. Способи і ознаки такі:

NameMethodSignDescriptionAddition__add__+Реалізує додавання. Subtraction__sub__–Реалізує віднімання.Multiplication__mul__*Реалізує multiplicationDivision__div__/Реалізує ділення.Floor division__floordiv__//Реалізує ділення на підлогу.

#2. Операції порівняння

Подібно до методів арифметичної магії, ці методи викликаються, коли екземпляр класу, для якого вони визначені, розміщується ліворуч від оператора порівняння. Також, як і арифметичні магічні методи, вони викликаються з двома параметрами; перший – це посилання на екземпляр об’єкта. Другий — посилання на значення з правого боку знака.

NameMethodSignDescriptionLess than__lt__<Реалізує менше ніж порівнянняGreater than__gt__>Реалізує більше ніж порівнянняEqual to__eq__==Реалізує рівне порівняннюLess ніж або дорівнює__le__>=Реалізує менше або дорівнює порівняннюGreater ніж або дорівнює__ge__<=Реалізує більше або дорівнює порівняння

#3. Операції життєвого циклу

Ці методи викликатимуться у відповідь на різні методи життєвого циклу об’єкта, наприклад створення екземпляра або видалення. До цієї категорії відноситься конструктор __init__. Загальні методи цієї категорії наведено в таблиці нижче.

  7 найкращих редакторів PDF на Mac для підвищення продуктивності

NameMethodDescriptionConstructor__init__Цей метод викликається щоразу, коли видаляється об’єкт класу, для якого він визначений. Його можна використовувати для виконання дій очищення, таких як закриття будь-яких відкритих файлів. Deletion__del__Цей метод викликається щоразу, коли видаляється об’єкт класу, для якого він визначений. Його можна використовувати для виконання дій очищення, таких як закриття будь-яких відкритих файлів. New__new__Метод __new__ викликається першим, коли створюється екземпляр об’єкта зазначеного класу. Цей метод викликається перед конструктором і приймає клас, а також будь-які додаткові аргументи. Він повертає екземпляр класу. Здебільшого це не дуже корисно, але докладно описано тут.

#4. Операції представництва

NameMethodDescriptionStr__str__Повертає зрозуміле людині рядкове представлення об’єкта. Цей метод викликається, коли ви викликаєте функцію str(), передаючи екземпляр класу як аргумент. Він також викликається, коли ви передаєте екземпляр до функцій print() і format(). Він призначений для надання рядка, зрозумілого кінцевому користувачеві програми. Repr__repr__Повертає рядкове представлення об’єкта, який використовується розробником. В ідеалі, повернутий рядок має бути насиченим інформацією, щоб ви могли створити ідентичний екземпляр об’єкта лише з рядка.

Найкращі практики створення магічних методів

Чарівні методи неймовірні і спростять ваш код. Однак під час їх використання важливо пам’ятати про наступне.

  • Використовуйте їх економно – впровадження занадто великої кількості чарівних методів у ваших класах ускладнює розуміння вашого коду. Обмежтеся виконанням лише найважливіших.
  • Перш ніж використовувати такі методи, як __setatrr__ і __getattr__, переконайтеся, що ви розумієте вплив на продуктивність таких методів.
  • Задокументуйте поведінку ваших магічних методів, щоб інші розробники могли точно знати, що вони роблять. Це полегшує їх використання та налагодження, коли це необхідно.

Заключні слова

У цій статті я представив магічні методи як спосіб створення класів, які можна використовувати з вбудованими операціями. Я також обговорив, як вони визначаються, і розглянув приклад класу, який реалізує магічні методи. Далі я згадав різні методи, які ви, ймовірно, збираєтеся використовувати та які вам знадобляться, перш ніж поділитися кількома найкращими практиками, які слід пам’ятати.

Далі ви можете дізнатися, як реалізувати клас Counter у Python.