170 похожих чатов

Товарищи, подскажите, почему декораторам обязательны замыкания? Вот не пойму, в

чём проблема в обычную, не замкающуюся функцию взять, передать туда функцию и всё это дело выполнить

40 ответов

35 просмотров

потому что не получится без замыкания использовать суть декоратора -то, что вызов функции не меняется, от того, что на нее навешан декоратор, а функционал изменяется. т.е. грубо говоря была у тебя функция: def bar(*args, **kwargs): pass а потом навесил на нее декоратор: @foo def bar(*args, **kwargs): pass и вот ты ее вызывал bar() до того как ее задекорировал и задекорировання она тоже вызывается как bar() а функционал у нее поменялся в зависимости от того, как его модифицировал декоратор

Не обязательны на самом деле

Все в реальности сложнее https://t.me/advice17/47

Джабир- Автор вопроса
Vladimir Strelets
потому что не получится без замыкания использовать...

Всё равно не понимаю. Почему декоратор не может просто взять, как в данном случае, и import time def timer(func): start = time.time() func() end = time.time() return end - start def someone_func(): time.sleep(2) передать функцию someone_func() в timer()? В чём проблема?

Джабир- Автор вопроса
Arkady Strugatsky
Не обязательны на самом деле

А как реализовать декоратор без замыкания?

Джабир
А как реализовать декоратор без замыкания?

Например с functools.partial() Алсо подозреваю что там замыкание под капотом

Tishka17
Все в реальности сложнее https://t.me/advice17/47

мм и что же по ссылке сложнее? то что могут быть декораторы отличающиеся от паттерна "Декоратор" ?)

Джабир
А как реализовать декоратор без замыкания?

Или просто вернуть функцию без изменений. В питоне декоратор это не только паттерн декоратор, но ещё используется чтобы где-то зарегистрировать функцию

Джабир- Автор вопроса
Arkady Strugatsky
Или просто вернуть функцию без изменений. В питоне...

Ну я имею ввиду конкретно то, что ставится через @

Arkady Strugatsky
def reg(func): registry.register(func) ret...

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

Джабир
Всё равно не понимаю. Почему декоратор не может п...

ну в примере который написали что делать если в функцию надо передать аргументы? городить прием в нее не только функции но и аргументов и вызов внутри с аргументами? в итоге оно будет работать, но вызывать надо будет именно функцию-таймер декоратор позволяет гибко настраивать функционал - захотели навесить декоратор дополнительно - навесили, не нужен больше - убрали, все изменения - в одном месте

Джабир- Автор вопроса
Vladimir Strelets
ну в примере который написали что делать если в фу...

import time def timer(func, *args, **kwargs): start = time.time() func(*args, **kwargs) end = time.time() return end def someone_func(*args, **kwargs): time.sleep(2) Т.е. я правильно понимаю, вы это имеете ввиду? Так всё равно же в замыкании функции которую мы вызываем также надо передать аргументы, предварительно их передав в подфункцию

Джабир- Автор вопроса
Arkady Strugatsky
def reg(func): registry.register(func) ret...

Не знаю что такое registry, но смею предположить то это тоже самое замыкание. Т.е. замыкание есть, но неявное

Vladimir Strelets
мм и что же по ссылке сложнее? то что могут быть ...

То что декоратор может вернуть совсем другую фигню или ту же функцию

Что значит замыкающаяся / не замыкающаяся функции, можно примеры?

Джабир
import time def timer(func, *args, **kwargs): ...

да, так я еще раз повторю: декоратор позволит более гибко управлять поведением функции (включать/выключать декорирование) с меньшими затратами сил

Джабир- Автор вопроса
Сергей
Что значит замыкающаяся / не замыкающаяся функции,...

https://www.youtube.com/watch?v=sJF7OMNgLUs Кратко говоря - функция, которая возвращает функцию. К возвращённой функции можно обращаться используя имена из основной, ибо основная не удаляется сборщиком мусора, ибо на неё ссылаются

Джабир
Не знаю что такое registry, но смею предположить т...

Это пример. Суть в том что ты регистрируешь функцию и возвращаешь ее же без изменений

Джабир- Автор вопроса
Vladimir Strelets
да, так я еще раз повторю: декоратор позволит боле...

Да! Я вас понимаю, но вопрос в том, почему блин декоратор использует именно замыкание? Он не может в обычную функцию запихать декорируемую и там её выполнить? Вот в чём непонятки

Джабир
Да! Я вас понимаю, но вопрос в том, почему блин де...

"Он не может в обычную функцию запихать декорируемую и там её выполнить?" как это может выглядеть (Если на псевдокоде)?

Давай проясним. В какой момент вызывается код декоратора?

Джабир- Автор вопроса
Джабир
В тот момент когда вызывается функция

Нет. Сразу после того как функция появилась в памяти

Джабир
Да! Я вас понимаю, но вопрос в том, почему блин де...

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

Джабир- Автор вопроса
Tishka17
Каждый конкретный декоратор может использовать или...

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

Джабир
Нужен доступ к аргументу самого декоратора? Но в д...

Я же написал, доступ к оригинальной функции, щас поправлю формадировку

Джабир
Нужен доступ к аргументу самого декоратора? Но в д...

могут передаваться аргументы для работы самого декоратора например декоратор с пробросом аргумента для ретраев вызова функции )

стоит дотошно разобраться в теме, тогда большая часть "магии" в декораторах пропадет) вот тут неплохая статья https://habr.com/ru/articles/141411/ а у Балакирева на selfedu замыкания и декораторы разобраны с примерами и схемами, должно помочь

Джабир- Автор вопроса
Джабир
Да, вот именно что я учился по selfedu

ну тогда как минимум то что происходит внутри замыкания должно быть понятно, но кажется стоит внимательно пересмотреть. и начать именно с замыканий, чтобы четко понимать - в какой момент происходит замыкание, что именно "замыкается" в сохраненной локальной области видимости и как оно вообще работает

Джабир- Автор вопроса
Vladimir Strelets
ну тогда как минимум то что происходит внутри замы...

Да, вот в замыканиях я вполне себе разобрался. Что-то ссылается на подфункцию, а раз что-то ссылается на подфункцию, сборщик мусора не трогает саму функцию. Ну а раз сборщик мусора не трогает саму функцию, нам доступны её имена и мы можем с ними чо угодно делать

Джабир- Автор вопроса
Tishka17
Каждый конкретный декоратор может использовать или...

А можно псевдопример, генерации новой функции? И ещё вопрос: использует или не использует замыкание - подразумевается, использует или не использует ту внешнюю область (т.е. область основной функции, не убираемой сборщиком)?

Джабир
А можно псевдопример, генерации новой функции? И ...

def func_generator(a): def inner_function(): print(a) return inner_function вот тебе генератор функции с замыканием

Джабир- Автор вопроса
Tishka17
def func_generator(a): def inner_function(): ...

Почему генератор? Это же же функция с замыканием, которая просто возвращает подфункцию, на которую можно ссылаться

Tishka17
Каждый конкретный декоратор может использовать или...

https://stackoverflow.com/questions/2497801/closures-are-poor-mans-objects-and-vice-versa-what-does-this-mean 😛

Джабир
import time def timer(func, *args, **kwargs): ...

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

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Карта сайта