Шаг 120.
Основы языка Python.
Пользовательские функции. Декораторы функций

    На этом шаге мы рассмотрим понятие декоратора и примеры использования декораторов.

    Декораторы позволяют изменить поведение обычных функций - например, выполнить какие-либо действия перед выполнением функции. Рассмотрим это на примере:

def deco(f): # Функция-декоратор
    print("Вызвана функция  func()")
    return f #  Возвращаем ссылку на функцию

@deco
def func (x):
    return "x = {0}".format(x)

print(func(10))
Архив с файлом можно взять здесь.

    Результат выполнения примера приведен на рисунке 1.


Рис.1. Результат работы приложения

    В этом примере перед определением функции func() указывается название функции deco() с предваряющим символом @:

  @deco

    Таким образом, функция deco() становится декоратором функции func(). В качестве параметра функция-декоратор принимает ссылку на функцию, поведение которой необходимо изменить, и должна возвращать ссылку на ту же функцию или какую-либо другую. Наш предыдущий пример эквивалентен следующему коду:

def deco(f):
    print("Вызвана функция func()")
    return f

def func(x):
    return "x = {0}".format(x)
# Вызываем функцию func() через функцию deco()
print(deco(func)(10))
Архив с файлом можно взять здесь.

    Перед определением функции можно указать сразу несколько функций-декораторов. Для примера обернем функцию func() в два декоратора: deco1() и deco2():

def deco1(f):
    print("Вызвана функция deco1()")
    return f

def deco2(f):
    print("Вызвана функция deco2()")
    return f

@deco1
@deco2
def func (x):
    return "x = {0}".format(x)

print(func(10))
Архив с файлом можно взять здесь.

    Результат выполнения примера приведен на рисунке 2.


Рис.2. Результат работы приложения

    Использование двух декораторов эквивалентно следующему коду:

  func = deco1(deco2(func))

    Здесь сначала будет вызвана функция deco2(), а затем функция deco1(). Результат выполнения будет присвоен идентификатору funс.

    В качестве еше одного примера использования декораторов рассмотрим выполнение функции только при правильно введенном пароле:

passw = input("Введите пароль: ")

def test_passw(p):
    def deco(f):
        if p == "10": # Сравниваем пароли
            return f
        else:
            return lambda: "Доступ закрыт"
    return deco # Возвращаем функцию-декоратор

@test_passw(passw)
def func():
    return "Доступ открыт"

print(func()) # Вызываем функцию
Архив с файлом можно взять здесь.

    В этом примере после символа @ указана не ссылка на функцию, а выражение, которое возвращает декоратор. Иными словами, декоратором является не функция test_passw(), а результат ее выполнения (функция deco()). Если введенный пароль является правильным, то выполнится функция func(), в противном случае будет выведена надпись "Доступ закрыт", которую возвращает анонимная функция (рисунок 3).


Рис.3. Результат работы приложения

    На следующем шаге мы рассмотрим рекурсию.




Предыдущий шаг Содержание Следующий шаг