Замыкания. Карринг. Декораторы.
Внутренние функции
Мы можем определить функцию внутри другой функции
def outer(a, b):
def inner(c, d):
return c + d
return inner(a, b)
outer(4, 7)
# 11Внутренние функции могут быть полезны при выполнении некоторых сложных задач более одного раза внутри другой функции. Это позволит избежать дублирования кода
Рассмотрим пример работы со строкой, когда внутренняя функция добавляет текст в свой аргумент:
def hello(saying):
def inner(name):
return f"Hello, {name}!"
return inner(saying)
hello("Igor")
# 'Hello, Igor!'Практика:
Напишите функцию, которая принимает аргумент — число. В теле функции определите внутреннюю функцию, которая принимает строку и число. Значение строки по умолчанию —
"Python". Число — это количество, сколько раз должна быть продублирована строка. Верните результат работы внутренней функции во внешней функции. Протестируйте программу.
Замыкания
Внутренняя функция может действовать как замыкание, если возвращает функцию
Замыкание — это функция, которая находится внутри другой функции и ссылается на переменные, объявленные в теле внешней функции
Применение замыканий позволяет создавать функции с доступом к переменным, находящимся вне их области видимости и запоминать значения переменных
Внутри внешней функции мы можем создавать переменные и изменять их во внутренних функциях
Для этого используется ключевое слово
nonlocalПример использования замыкания и ключевого слова
nonlocalдля генерации ID:
Практика:
Напишите функцию которая принимает имя в качестве аргумента и добавляет к имени заданную строку. Используйте замыкание.
Пример работы программы:
Создайте функцию для генерации паролей. Функция должна принимать символы, из которых будет генерироваться пароль (установите для этого значение по умолчанию), и длину пароля. При каждом вызове она должна возвращать новый случайный пароль. Используйте замыкание и модули
randomиstring
Пример работы программы:
Карринг
Карринг (currying) — это техника в функциональном программировании, при которой функция, принимающая несколько аргументов, преобразуется в последовательность функций, каждая из которых принимает по одному аргументу.
Это позволяет вам создавать более специализированные функции и частично применять аргументы.
Ещё один пример:
Карринг удобен, когда вы хотите создавать множество функций, используя один и тот же "шаблон" и частично применять аргументы.
Практика:
Создайте функцию умножения двух чисел. Используйте карринг
Декораторы
Иногда нам нужно модифицировать существующую функцию, не меняя при этом исходный код
Декоратор — это функция, которая принимает одну функцию в качестве аргумента и возвращает другую функцию. По сути это "обертка" для нашей функции, которая добавляет ей функционал
Добавим аргументы и создадим дополнительную переменную для задекорированной функции:
Для того чтобы сделать декоратор универсальным, можно сразу указать все возможные аргументы (позиционные и ключевые) таким образом:
В Python есть "синтаксический сахар" — более удобная форма записи для декораторов:
Пример — декоратор, измеряющий время работы функций:
Практика:
Напишите функцию конкатенации двух строк. Измерьте время её работы при помощи декоратора
test_timeОпределите декоратор
test, который выводит строкуstartпри вызове функции и строкуend, когда функция завершает свою работу. Дополнительно: добавьте вывод имени запускаемой функции (используйте методfunc.__name__)Напишите декоратор, который возводит результат работы функции в квадрат. Примените его к любой функции, возвращающей число.
Напишите декоратор, который будет автоматически повторять выполнение функции, если она выбрасывает исключение.
Last updated