Python Декораторы: Добавление Сверхсил к Вашим Функциям
Привет, стремящиеся к мастерству в Python! Сегодня мы погружаемся в увлекательный мир Python декораторов. Представьте декораторы как магические обертки, которые могут улучшить ваши функции сверхсилами. Волнующе, правда? Давайте отправимся в эту путешествие вместе!
Что Такое Декораторы?
Представьте, что у вас есть прекрасно упакованный подарок. Упаковка не изменяет сам подарок, но делает его выглядеть лучше, верно? Вот что и делают декораторы с вашими функциями в Python. Они оборачивают ваши функции, добавляя дополнительную функциональность, не изменяя при этом саму оригинальную функцию.
Начнем с простого примера:
def мой_декоратор(func):
def обертка():
print("Что-то происходит перед вызовом функции.")
func()
print("Что-то происходит после вызова функции.")
return обертка
@мой_декоратор
def скажи_привет():
print("Привет!")
скажи_привет()
Если вы выполните этот код, вы увидите:
Что-то происходит перед вызовом функции.
Привет!
Что-то происходит после вызова функции.
Разберем это:
- Мы определяем декоратор функции
мой_декоратор
, который принимает функцию в качестве аргумента. - Внутри
мой_декоратор
, мы определяем функциюобертка
, которая добавляет некоторое поведение до и после вызова оригинальной функции. - Мы используем синтаксис
@мой_декоратор
, чтобы применить наш декоратор к функциискажи_привет
. - Когда мы вызываем
скажи_привет()
, на самом деле мы вызываем обернутую версию функции.
Ни что себе! Мы только что добавили некоторое дополнительное поведение к нашей функции скажи_привет
, не изменяя ее код!
Декораторы с Аргументами
Но подождите, еще больше! Что если наша функция принимает аргументы? Нет проблем! Мы можем изменить наш декоратор, чтобы обрабатывать это:
def мой_декоратор(func):
def обертка(*args, **kwargs):
print("Перед вызовом функции.")
result = func(*args, **kwargs)
print("После вызова функции.")
return result
return обертка
@мой_декоратор
def сложить(a, b):
return a + b
print(сложить(3, 5))
Это выведет:
Перед вызовом функции.
После вызова функции.
8
Здесь *args
и **kwargs
позволяют нашему декоратору работать с любым количеством позиционных и именованных аргументов.
Встроенные Декораторы
Python приходит с некоторыми встроенными декораторами, которые чрезвычайно полезны. Давайте их рассмотрим!
Декоратор @classmethod
Декоратор @classmethod
используется для определения методов, которые работают на самом классе, а не на экземплярах класса.
class Пицца:
def __init__(self, ингредиенты):
self.ингредиенты = ингредиенты
@classmethod
def маргарита(cls):
return cls(['моцарелла', 'томаты'])
@classmethod
def просиutto(cls):
return cls(['моцарелла', 'томаты', 'ветчина'])
print(Пицца.маргарита().ингредиенты)
print(Пицца.просиutto().ингредиенты)
Это выведет:
['моцарелла', 'томаты']
['моцарелла', 'томаты', 'ветчина']
Здесь маргарита
и просиutto
являются классовыми методами, которые создают и возвращают новые экземпляры Пиццы с предопределенными ингредиентами.
Декоратор @staticmethod
Статические методы — это методы, которые не работают ни на экземпляре, ни на классе. Это просто обычные функции, которые случайно находятся внутри класса.
class Математика:
@staticmethod
def сложить(a, b):
return a + b
print(Математика.сложить(5, 10))
Это выведет:
15
Декоратор @property
Декоратор @property
позволяет определять методы, которые можно доступить как атрибуты.
class Круг:
def __init__(self, радиус):
self._радиус = радиус
@property
def радиус(self):
return self._радиус
@property
def площадь(self):
return 3.14 * self._радиус ** 2
c = Круг(5)
print(c.радиус)
print(c.площадь)
Это выведет:
5
78.5
Здесь мы можем доступить радиус
и площадь
, как если бы они были атрибутами, но на самом деле они являются методами.
Декоратор @functools.wraps
Этот декоратор используется для сохранения метаданных оригинальной функции при создании декораторов.
from functools import wraps
def мой_декоратор(func):
@wraps(func)
def обертка(*args, **kwargs):
"""Это обертывающая функция"""
return func(*args, **kwargs)
return обертка
@мой_декоратор
def моя_функция():
"""Это моя функция"""
pass
print(моя_функция.__name__)
print(моя_функция.__doc__)
Это выведет:
моя_функция
Это моя функция
Без @wraps
, имя функции и документация были бы теми, что у обертывающей функции.
Заключение
Декораторы — это мощная функция в Python, которая позволяет изменять или улучшать функции и методы. Они широко используются в фреймворках и библиотеках для добавления функциональности, такой как логирование, контроль доступа и многое другое.
Помните, ключ к владению декораторами — это практика. Попробуйте создать свои собственные декораторы и применить их к различным функциям. Скоро вы будете оборачивать ваши функции сверхсилами как профи!
Вот таблица, подводящая итог декораторов, которые мы рассмотрели:
Декоратор | Назначение |
---|---|
@classmethod |
Определять методы, которые работают на самом классе |
@staticmethod |
Определять методы, которые не работают ни на экземпляре, ни на классе |
@property |
Определять методы, которые можно доступить как атрибуты |
@functools.wraps |
Сохранять метаданные оригинальной функции в декораторах |
Счастливого кодирования, и пусть ваши функции всегда украшены красиво!
Credits: Image by storyset