Почему декоратор в python вызывается при старте скрипта? Обнаружил странное поведение в python3.5. Пишем тупой код с декоратором:def foo(f): print("foo") f() @foo def bar(): print("bar") И теперь при попытке запустить скрипт, содержащий только эти строки, он вызывает декорируемую функцию, а если попытаться сделать еще что-то такое:print (bar) То сначала вновь вызовется декорируемая функия, а после выведется None. Мне казалось, что декораторы - это синтаксический сахар в python и по идее должен только при вызове функции bar подменять этот вызов на foo(bar). Я что-то не правильно понимаю, или это косяк в python?
Декораторы в Python вызываются при определении функции, а не при вызове. При определении функции bar, происходит вызов декоратора foo, что приводит к выводу "foo", после чего сама функция bar неявно вызывается и выводит "bar".
Когда вы далее пытаетесь вывести bar, он уже определен и вызывается еще раз, что приводит к повторному вызову декоратора foo и последующему выводу "bar". После этого вы печатаете None, потому что функция bar не возвращает никакого значения, поэтому по умолчанию возвращается None.
Это поведение декораторов в Python и оно соответствует их назначению - модификация поведения функции при ее определении, а не при вызове. Если вы хотите отложить вызов декоратора до момента вызова функции, вам нужно будет использовать функциональный подход.
Декораторы в Python вызываются при определении функции, а не при вызове. При определении функции bar, происходит вызов декоратора foo, что приводит к выводу "foo", после чего сама функция bar неявно вызывается и выводит "bar".
Когда вы далее пытаетесь вывести bar, он уже определен и вызывается еще раз, что приводит к повторному вызову декоратора foo и последующему выводу "bar". После этого вы печатаете None, потому что функция bar не возвращает никакого значения, поэтому по умолчанию возвращается None.
Это поведение декораторов в Python и оно соответствует их назначению - модификация поведения функции при ее определении, а не при вызове. Если вы хотите отложить вызов декоратора до момента вызова функции, вам нужно будет использовать функциональный подход.