Декораторы

Декораторы

Limera1n

Мы подошли к одной из продвинутых тем, которая называется декораторы. И прежде чем разобраться что такое декораторы, нам нужно разобраться, что из себя представляют функции в питоне. А функции в питоне представляют полноценные объекты, это значит, что функции могут быть возвращены из функции и функции могут быть переданы в функцию в качестве аргумента.

Начнем с простых примеров:

Для чего я написал эту функцию? Чтобы продемонстрировать, что функция это полноценный объект и функция может быть присвоена переменной. Мы можем создать переменную с именем hello2 и присвоить ей имя нашей функции. Заметьте, что я не прописал круглые скобочки, я не делаю вызов функции, я ссылку на эту функцию присваиваю переменной. Если мы без прописывания круглых скобочек выведем результат hello2, то мы увидим, что это функция, которая находится в основном скрипте (__main__). А если мы выводим результат используя круглые скобочки, то получаем Hello, world!, потому что hello2() содержит ссылку на функцию hello_world, то есть, если мы вызовем функцию находящуюся по этому адресу, то отработает функция hello_world.

Так же функции можно возвращать из функций. Например:

Тут мы определяем функцию внутри функции. Эта функция выводит наш текст. А из функции hello_world мы возвращаем функцию internal, теперь мы можем вызвать hello_world. То есть из функции hello_world будет возвращена ссылка на функцию internal и теперь мы можем вызвать функцию hello_world и получить ссылку на функцию internal. В выводе видно, что здесь ссылка идет на внутреннюю функцию <locals>.internal. И если мы вызовем функцию hello2(), то получим все тот же вывод.

Все это нужно для понимания, как работают декораторы. А прежде чем мы перейдем, я покажу, что функции могут принимать в качестве аргумента другие функции. Например:

В качестве аргумента мы передали функцию hello_world, заметьте, что мы не вызываем сами здесь hello_world(), мы передаем ссылку на функцию.

Надеюсь это все понятно, однако, непонятно к чему я клоню. Декораторы, это функции которые содержат в себе некую обертку, с помощью которой можно обернуть функцию, передаваемую в качестве аргумента. Давайте покажу пример:

Внутри функции у нас обертка wrap, эта функция, которая в самом начале выводит некий текст с функцией, затем мы вызываем этот func(), и в конце пишем другой текст и возвращаем функцию wrap. Создаем функцию hello.

Чтобы воспользоваться этим декоратором мы создаем переменную, которой присваиваем функцию log_decorator(hello), а затем выводим ее. Вывод мы получаем вот такой. Сначала у нас выводится, что мы вызываем такую то функцию, затем отрабатывает сама эта функция, и в конце выводится, что функция завершила работу. Это декоратор, который мы использовали вручную. Однако Python упрощает работу декораторов с помощью значка @. Пример:

Эта функция hello() автоматически будет передана интерпретатором в функцию log_decorator, и произойдет все то же самое. Вот таким простым образом мы можем употреблять декораторы.

Кстати, декораторы используются в таких фреймворках, как django.

Report Page