Pull to refresh

Comments 16

Или я статью криво прочитал или как, но декоратор wraps(fnc) просто выставляет в декорируемой им функции __name__, __doc__ и тд на значения из функции fnc. Никакого волшебства он не делает и всё будет работать и без него. Он нужен в основном для правильных стэк трейсов и дебага.
Извините, но я не очень себе представляю как можно получить доступ к параметрам декорируемой функции «и без него» не написав аналогичный декоратор. Про волшебство я ничего не писал…
> Я затрудняюсь человеческим языком, не запутав читателя в терминах, вразумительно сформулировать то, что тут происходит

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

check_nickname не декоратор, это фабрика декораторов. использовать вы ее будете как @check_nickname(), то есть вызовете, она вернет декоратор, который и применится к функции.

check — реальный декоратор, примет в качестве параметра функцию, и вернет вместо нее другую. Вот тут и нужен wraps, чтобы всякие атрибуты функции типа __name__, __doc__ etc скопировать на новую функцию.

Остался wrapper — обычная функция, которая будет вызвана вместо оригинальной функции, с параметрами соответственно. Может перешаманить параметры, может обработать результат вызова обернутой функции. А может вообще ее не вызывать, и вернуть что-нибудь другое.

Замечания по коду — check_nickname принимает зачем то args и kwargs — они не используются, не пишите «на всякий случай» никогда, это сродни ""«try… except:»"".
Ах, да. Так как check_nickname собственно никакой смысловой нагрузки не несет, то его можно спокойно выкинуть — вам здесь фабрика ни к чему собственно.
действительно вы правы. тут мой косяк — бездумно слизал код с @login_required, подправил код.
убрал, опять же «слизал»…
Я заметил, что декоратор @login_required не требует передачи в себя каких-либо данных, т.е. он их получает из декорируемой функции сам.

Не из декорируемой функции а из параметров передаваемых в нее.
В целом сумбур, для начала хорошенько разберитесь с декораторами сами.

Нюансы терминологии. Декоратор декорирует всё же функцию, а не её данные. Сначала он получает её, а потом уже доступается к её данным с помощью wraps и именно об этом заметка.
Да не «доступается» он с помощью wraps, можете выкинуть этот wraps спокойно, и все будет работать.
Он вообще никуда не доступается, он возвращает функцию взамен оригинальной, вот и вся недолга.
Собственно для того я его и использовал — вернуть функцию… Но я его удалил и всё работает. Получается в декоратор check_nickname передаётся функция, которая исполняется внутри wrapper, который в свою очередь, и возвращается декоратором взамен оригинальной функции. Соответственно в оригинальном коде вызов идёт уже к wrapper и он получает все параметры обёрнутой функции, проверяет их и либо исполняет её, либо нет! Спасибо огромное за ваши комменнтарии. Всё-таки есть польза от этой заметки, хоть и не такая как я изначально предполагал :) Мне действительно нехватало понимания принципа работы декораторов. Сейчас перепишу заметку…
Но вы были правы в том, что мне нужно лучше разобраться с декораторами.
Написали свой первый декоратор на питоне и решили поделиться этим на хабре?
Второй, в любом случае, судя по счётчику избранного, эта заметка оказалась полезной не только для меня…
Sign up to leave a comment.

Articles