Објашњење Питхон декоратера: од @проперти до поновног покушаја логике за 15 минута (2026)
Декоратори су карактеристика која раздваја „зна Питхон“ од „течно чита Питхон“. Изгледају магично, али су механички: @decorator на функцији је тачно f = decorator(f). То је то. Све остало у овом туторијалу је та једна линија примењена у различитим облицима.
Теорија једне линије
Када пишете:
Питхон га трансформише у:
То је цели механичар. @decorator_name изнад def покреће def_name = decorator_name(def_name) након дефиниције. Ако ово интернализујете, декоратери заувек престају да буду мистериозни.
Писање вашег првог декоратера (60 секунди)
Декоратор је било који позив који узима функцију и враћа функцију. Типичан облик:
*args, **kwargs у омоту је одбрамбени образац — омогућава декоратеру да ради на било којој функцији без обзира на потпис. Прескочите то и добићете TypeError: wrapper() takes 0 positional arguments but 2 were given у тренутку када неко декорише функцију параметрима.
Исправка @functools.wraps
Једна суптилна грешка: након украшавања, add.__name__ је "wrapper", а не "add". Докстрингови и наговештаји типа такође нестају. Исправка је један увоз:
Правило: сваки декоратор који напишете треба да користи `@functools.wraps(fn)`. Кошта један ред и спречава читаву категорију проблема са отклањањем грешака (интроспекција, pytest инструменти, logging форматери, pickle — све се тихо прекида без тога).
Четири декоратера које ћете видети у свакој бази кода
1. @property — израчунати атрибути
@property чини метод који се може позвати као да је атрибут. Савршено за изведене вредности само за читање. Постоји и @area.setter за путању писања, али 90% употребе @property је само за читање.
2. @staticmethod и @classmethod
@classmethod добија cls (саму класу) и користи се за алтернативне конструкторе. @staticmethod не добија ништа посебно и обична је функција која једноставно живи унутар именског простора класе.
3. @functools.cache — мемоизација
Један од најмоћнијих стдлиб декоратера. Аутоматски меморише функцију на основу њених аргумената. Захтева да се сви аргументи могу хеширати (без листа/диктова као аргумената — користите тупле).
4. @dataclasses.dataclass — елиминација шаблона
@dataclass чита напомене типа на нивоу класе и аутоматски генерише __init__, __repr__, __eq__ и (са frozen=True) __hash__. То је највеће побољшање квалитета живота у Питхон-у 3.7+.
Писање декоратора @retry (пример из стварног света)
Декоратор који поново покушава функцију у случају неуспеха са експоненцијалним повлачењем:
Обратите пажњу на три угнежђене функције: retry прихвата аргументе конфигурације и враћа decorator; decorator прихвата функцију и враћа wrapper; wrapper покреће петљу поновног покушаја. Овај трослојни образац је како изгледа сваки декоратер-са-аргументима — запамтите облик, а не конкретан пример.
Декоратери засновани на класи (ретко, али корисно)
Декоратер се може позвати. Часови са __call__ такође раде:
Користи се када декоратер треба да задржи стање које наџивљава један позив (бројац, кеш, сегмент за ограничење брзине).
Уобичајене замке
1. Заборављање `@functools.wraps` — интроспекција се тихо прекида.
2. Променљиви подразумевани аргументи у самом декоратору — класична грешка def wrapper(x, cache=[]) такође се јавља овде.
3. Декорисање метода без прихватања `self` — запамтите self је само позициони аргумент; *args, **kwargs добро хвата.
4. Наредба је важна при слагању: @a\n@b\ndef f() је f = a(b(f)). Читајте стекове одоздо према горе.
Вежбајте
Напишите декоратер @timing који штампа колико дуго је упакованој функцији потребно да се покрене, а затим га примените на функцију која израчунава sum(range(10_000_000)). Цео декоратор је 8 линија са functools.wraps + time.perf_counter.
Једном када усвојите да је @x f = x(f), декоратери постају једна од најпродуктивнијих карактеристика Питхон-а. Они су свуда у правим кодним базама: Фласк/ФастАПИ руте (@app.route), питест фиктурес (@pytest.fixture), Дјанго прикази (@login_required), Пидантиц валидатори (@field_validator). Научите да их сами пишете откључавате способност читања сваког од њих.
Следећи корак: 10 практичних лекција декоратера — направите @retry, @memoise, @rate_limit и @requires_auth од нуле са правим Питхон-ом који ради у вашем претраживачу.