Друкарня від 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

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

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

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

  • CRM keyCRM: зручне рішення для продажів, комунікацій і керування командою

    Успіх компанії залежить від того, наскільки швидко вона здатна опрацьовувати вхідні запити. Коли дані про клієнтів розпорошені між різними месенджерами, виникає хаос. CRM keyCRM пропонує вихід із цієї ситуації, об’єднуючи всі робочі процеси в єдиному зручному інтерфейсі.

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

    Crm
  • Різниця між UX і UI, яку варто зрозуміти ще до першого заняття

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

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

    Ui-ux
  • Логіка змін: як SEO оптимізація прибирає бар’єри до зростання

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

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

    Seo
  • Музичний футуризм: неймовірні інструменти XXI століття

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

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

    Музичні Інструменти
  • Стіл – всьому голова? Так, якщо його правильно підібрати

    Коли починаєш вивчати пропозицію меблевих фабрик щодо столів, дивуєшся кількості варіантів, адже вони пропонують різні розміри, різні матеріали, різноманітні форми та дизайни. Скористайтесь нашим каталогом MebelOK, щоб Ви могли підібрати найкращу модель для Вашого приміщення

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

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

Python SDET @ ajax.systems

6Довгочити
870Перегляди
18Підписники
Підтримати
На Друкарні з 14 квітня 2023

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

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

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

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

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