JavaRush /Курсы /Модуль 1: Python Core /Вся мощь декораторов

Вся мощь декораторов

Модуль 1: Python Core
8 уровень , 5 лекция
Открыта

6.1 Декораторы для методов классов

Декораторы также могут использоваться для методов классов. Важно помнить, что для методов классов необходимо правильно передавать аргументы self или cls.

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


def log_method_call(func):
    def wrapper(self, *args, **kwargs):
        print(f"Вызов метода {func.__name__}")
        return func(self, *args, **kwargs)

    return wrapper
        
class MyClass:
    @log_method_call
    def say_hello(self):
        print("Hello from MyClass!")
        
obj = MyClass()
obj.say_hello()

Объяснение

Декоратор (log_method_call): Этот декоратор принимает метод func и возвращает новую функцию wrapper, которая выводит сообщение перед вызовом метода.

Метод класса с декоратором (say_hello): Метод say_hello обернут декоратором log_method_call, что добавляет дополнительное поведение при его вызове.

Вывод:


Вызов метода say_hello
Hello from MyClass!

6.2 Несколько декораторов

Вы можете использовать несколько декораторов для одной функции, накладывая их друг на друга. Декораторы применяются в порядке, обратном их объявлению.


def decorator1(func):
    def wrapper():
        print("Декоратор 1")
        func()

    return wrapper
        
def decorator2(func):
    def wrapper():
        print("Декоратор 2")
        func()

    return wrapper
        
@decorator1
@decorator2
def say_hello():
    print("Hello!")
        
say_hello()

Объяснение

Декораторы (decorator1 и decorator2): Эти декораторы добавляют свои сообщения перед вызовом функции func.

Функция с декораторами (say_hello): Функция say_hello обернута обоими декораторами. Сначала применяется decorator2, затем decorator1.

Вывод:


# Декоратор 1
# Декоратор 2
Hello!

6.3 Встроенные декораторы

Python предоставляет несколько встроенных декораторов для стандартных задач, таких как статические методы, методы класса и свойства.

@staticmethod

Декоратор @staticmethod используется для создания статического метода, который не требует экземпляра класса для вызова.


class MyClass:
    @staticmethod
    def static_method():
        print("Это статический метод.")
        
MyClass.static_method()

@classmethod

Декоратор @classmethod используется для создания метода класса, который принимает класс (а не экземпляр) в качестве первого аргумента.


class MyClass:
    @classmethod
    def class_method(cls):
        print(f"Это метод класса {cls.__name__}.")
        
MyClass.class_method()

@property

Декоратор @property используется для создания геттеров, сеттеров и делетеров для атрибутов.


class MyClass:
    def __init__(self, value):
        self.hidden_value = value
        
    @property
    def value(self):
        return self.hidden_value
        
    @value.setter
    def value(self, new_value):
        self.hidden_value = new_value
        
obj = MyClass(10)
print(obj.value)  # Вывод: 10
obj.value = 20
print(obj.value)  # Вывод: 20

Это встроенные декораторы, их правильную работу обеспечивает сам интерпретатор Python.

6.4 Примеры использования декораторов

Логирование

Декораторы могут быть использованы для логирования вызовов функций и методов.


def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"Вызов функции {func.__name__} с аргументами {args} и {kwargs}")
        return func(*args, **kwargs)

    return wrapper
        
@log_call
def add(x, y):
    return x + y
        
print(add(2, 3))

Контроль доступа

Декораторы могут быть использованы для контроля доступа к функциям и методам.


def require_authentication(func):
    def wrapper(*args, **kwargs):
        if not args[0].is_authenticated:
            raise PermissionError("Пользователь не аутентифицирован.")
        return func(*args, **kwargs)
        
    return wrapper
        
class User:
    def __init__(self, is_authenticated):
        self.is_authenticated = is_authenticated
        
    @require_authentication
    def view_profile(self):
        print("Профиль пользователя")
        
user = User(is_authenticated=True)
user.view_profile()  # Успешный вызов
        
user2 = User(is_authenticated=False)
user2.view_profile()  # PermissionError: Пользователь не аутентифицирован.

Кэширование

Декораторы могут быть использованы для кэширования результатов функции.


def cache(func):
    cached_results = {}

    def wrapper(*args):
        if args in cached_results:
            return cached_results[args]
        result = func(*args)
        cached_results[args] = result
        return result

    return wrapper

@cache
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(35))
2
Задача
Модуль 1: Python Core, 8 уровень, 5 лекция
Недоступна
Множество декораторов.
Множество декораторов.
2
Задача
Модуль 1: Python Core, 8 уровень, 5 лекция
Недоступна
Длительность работы.
Длительность работы.
Комментарии (29)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
AndreyCDO Уровень 14
8 ноября 2025
Всё было хорошо, пока не началась тема с функциями высших порядков и декораторами... В этот момент я подумал что где-то очень медленно моргнул... И только когда начал читать комментарии понял, что это не во мне дело. К счастью, есть ИИ, который очень хорошо построчно объясняет что тут вообще происходит! Очень рекомендую.
Миракбар Уровень 16
22 октября 2025
import time def time_decorator(func): def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) elapsed = time.time() - start print(elapsed) return result return wrapper @time_decorator def compute_square(n): print(n ** 2) time.sleep(1) compute_square(3)
shinobi Уровень 19
29 июля 2025
Отлично, 10 лекций где задачи это ктрл в ктрл ц, причём 1в1, и тут бац - сделайте задачу про время. а какую библиотеку импортировать и как с ней работать - это уже сами подумайте. Браво, автор, небось нейронка по ошибке накинула в примеры тайм, и автор как обычно слизывая с нейронки не удосужился ничего сделать или поменять, и просто вставил
Slevin Уровень 64
1 июля 2025
Прикиньте рассказывать про встроенные декораторы - методы классов, не рассказав абсолютно ничего про классы, что это такое и как выглядит... А нам и прикидывать не нужно 😂🤣
Slevin Уровень 64
1 июля 2025
Также, во втором задании, воспользуемся библиотекой, про которую вы ничего не знаете и не слышали. Удачи! 🤣🤣🤣
Tatiana Уровень 22
24 июня 2025

import time

def time_decorator(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        time.sleep(1)
        result = func(*args, **kwargs)
        elapsed = time.time() - start
        print(elapsed)
        return result
    return wrapper

@time_decorator
def compute_square(n):
    print(n ** 2)

compute_square(3)
SWK Уровень 26
3 апреля 2025
"чтобы можно было наблюдать за работой декораторов", как написано в задаче №1, нужно наворотить что-то такое, как минимум:

def decorator1(func):
    def wrapper1(*args, **kwargs):
        print(f"Call wrapper1")
        print(f"Вызов функции {func.__name__} с аргументами {args} и {kwargs}")
        result = func(*args, **kwargs)
        print(f"End wrapper1")
        return result

    return wrapper1

def decorator2(func):
    def wrapper2(*args, **kwargs):
        print(f"Call wrapper2")
        print(f"Вызов функции {func.__name__} с аргументами {args} и {kwargs}")
        result = func(*args, **kwargs)
        print(f"End wrapper2")
        return result

    return wrapper2

@decorator1
@decorator2
def say_hello():
    print("Hello!")

say_hello()

Не надо удалять это "как решение", это не решение, здесь много лишнего.
Slevin Уровень 64
1 июля 2025
Хотел выложить такое же, пока не дописал вывод декоратора После функции - не особо понимал их формат вывода: func = decorator1(decorator2(func))
Дмитрий Уровень 27
25 февраля 2025
В первой задаче добавьте требование, чтобы функция say_hello вызывала функцию print, раз уж отсутствие этой функции является условием не принятия задачи.
Andrey Kochegarov Уровень 64
19 февраля 2025
наконец-то появилась интересная(не ctrl-c ctrl-v) задача. пришлось вернуться к лекции по генераторам.
Николай Уровень 17
19 февраля 2025
Я всё понимаю, так как учил это на других курсах. Но я не понимаю как это могут понять те, которые до этой темы не проходили все эти декораторы и классы на нормальных курсах 😯
Александр Уровень 19 Expert
18 февраля 2025
Эта лекция у меня в голове: "Вот смотрите, это тра-та-та. А еще может быть ту-ру-ру ! И вот посмотрите: та-ра-ра ту-ру-ру-ру ! Ну а это вы и сами видите что ыдвлаождфы рвадлфоывр адлфыовра длофвыра длфо ырвадлор фвыадло рфдлвыо ардлфоывар дфлывоарфд лывр фдлывор фдывло рфдлвыоа рфдлывор ! Держитесь друзья, следующая лекция снова нормальная, я только что оттуда )))
Николай Уровень 17
19 февраля 2025
Следующая лекция тоже очень странная. Она относится к 6му уровню, когда рассказывали про функции.
SWK Уровень 26
3 апреля 2025
Если не секрет, зачем вы болтаетесь туда-сюда, как в проруби?