Друкарня від WE.UA

Пайтон: декоратори - як і навіщо?

Входячи в пайтон-розробку, кожен дев точно стикався з цим явищем, бо декоратори присутні у каждому, просто у каждому сучасному фреймворці Пайтона

То, що ж це таке?

Декоратори — функції, що обгортують іншу функцію, надаючи додаткову логіку або взагалі замінюючи її. Замість функцій можуть бути використані класи, але це вже зовсім інша історія 😅

Це, можна сказати, один з механізмів наслідування, але зі світу функціонального програмування. І так легко пишеться хороший код — жодного доступу до зміни внутрішньої поведінки, тільки розширення, а це один з принципів SOLID 🤓
Думаю саме тому декоратори стали такими популярними 😍

Приклади використання

Реєстрація функції як callback, для серверу чи бота

# https://fastapi.tiangolo.com/#example
@app.get('/items/{item_id}')
def read_item(item_id: int, q: Union[str, None] = None):
    return {'item_id': item_id, 'q': q}

Просте кешування

# https://docs.python.org/3/library/functools.html#functools.lru_cache
@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

Промаркувати функцію для подальшого використання, не змінюючи її
(в цьому випадку у функції додається атрибут pytestmark)

# https://docs.pytest.org/en/7.1.x/how-to/skipping.html#skipping-test-functions
import sys


@pytest.mark.skipif(sys.version_info < (3, 10), reason="requires python3.10 or higher")
def test_function():
    ...

Заміна метода дескриптором

# https://docs.python.org/3/library/functions.html#property
class Parrot:
    def __init__(self):
        self._voltage = 100000

    @property
    def voltage(self):
        """Get the current voltage."""
        return self._voltage

Що ж, пора й самому щось написати ? 😁

Приклад написання

def timeit(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        result = f(*args, **kwargs)
        total_time = time.perf_counter() - start_time
        print(
            f'Function {f.__name__}, args: {args}, kwargs: {kwargs} '
            f'took {total_time:.2f} seconds'
        )
        return result
    return wrapper

Тут, ми водночас, використовуємо інший декоратор — @functools.wraps, який є каноном для функцій-обгорток, і дозволяє нам не змінювати назву оригінальної функції. Без нього, після створення функції з використанням декоратора, кінцевий користувач буде бачити в логах незрозумілу для нього функцію wrapper

Насправді, в декораторах немає нічого складного, якщо розуміти, що нижні два приклади є цілком ідентичними для Пайтону:

@timeit
def add(a, b):
    return a + b
def add(a, b):
    return a + b
add = timeit(add)

І тут єдине, що робить Пайтон — дає дуже зручний спосіб використання

У прикладі з timeit та lru_cache, додаткова логіка застосовується при виклику функції, і викликається оригінальна функція, без зміни аргументів. Не бачу особливого сенсу розбирати деталі, але якщо є такий запит, пишіть у коментарях 💬

Q&A

Якщо у вас все ще залишились запитання про декоратори у пайтоні, як чи навіщо їх писати — завжди готовий відповісти у коментарях

Усім добра та мирного неба над головою ❤️

Статті про вітчизняний бізнес та цікавих людей:

  • Вітаємо з Різдвом Христовим!

    Друкарня та платформа WE.UA вітають всіх наших читачів та авторів зі світлим святом Різдва! Зичимо всім українцям довгожданого миру, міцного здоровʼя, злагоди, родинного затишку та втілення всього доброго і прекрасного, чого вам побажали колядники!

    Теми цього довгочиту:

    Різдво
  • Каблучки – прикраси, які варто купувати

    Ювелірні вироби – це не тільки спосіб витратити гроші, але і зробити вигідні інвестиції. Бо вартість ювелірних виробів з кожним роком тільки зростає. Тому купуючи стильні прикраси, ви вигідно вкладаєте кошти.

    Теми цього довгочиту:

    Як Вибрати Каблучку
  • П'ять помилок у виборі домашнього текстилю, які псують комфорт сну

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

    Теми цього довгочиту:

    Домашній Текстиль
  • Як знайти житло в Києві

    Переїжджаєте до Києва і шукаєте житло? Дізнайтеся, як орендувати чи купити квартиру, перевірити власника та знайти варіанти, про які зазвичай не говорять.

    Теми цього довгочиту:

    Агентство Нерухомості
  • Як заохотити дитину до читання?

    Як залучити до читання сучасну молодь - поради та факти. Користь читання для дітей - основні переваги. Розвиток дітей - це наше майбутнє.

    Теми цього довгочиту:

    Читання
Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Вітя
Вітя@kor0p

Python SDET @ ajax.systems

850Прочитань
10Автори
18Читачі
Підтримати
На Друкарні з 14 квітня

Більше від автора

  • Пайтон: дескриптори - що це???

    Можливо, навіть далеко не всі чули, що таке дескриптори, але точно всі використовували їхЯ кажу це так впевнено, оскільки @property є дескриптором

    Теми цього довгочиту:

    Програмування
  • Майбутнє фронтенду — Пайтон?🤔

    PyWeb - фронтенд фреймворк, написаний на Пайтоні, мого авторства 🤓 Щоб запускати Пайтон в браузері використовується Pyodide та WebAssembly

    Теми цього довгочиту:

    Python

Це також може зацікавити:

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Це також може зацікавити: