Prejsť na hlavný obsah
Stredne pokročilý Python2026-07-29 · 10 min čítania

Python Decorators Explained: From @property to Retry Logic in 15 minutes (2026)

Dekorátory sú funkciou, ktorá oddeľuje „pozná Python“ od „plyne číta Python“. Vyzerajú magicky, ale sú mechanické: @decorator na funkcii je presne f = decorator(f). To je všetko. Všetko ostatné v tomto návode je, že jedna čiara je aplikovaná v rôznych tvaroch.

Teória jedného riadku

Keď píšeš:

▶ PYTHONeditable · runs in your browser

Python ho transformuje na:

▶ PYTHONeditable · runs in your browser

To je celý mechanik. @decorator_name nad def spúšťa def_name = dekorator_name(def_name) po definícii. Ak si to osvojíte, dekoratéri prestanú byť navždy tajomní.

Písanie svojho prvého dekoratéra (60 sekúnd)

Dekorátor je akýkoľvek volateľný prvok, ktorý preberá funkciu a vracia funkciu. Typický tvar:

▶ PYTHONeditable · runs in your browser

„args, *kwargs“ v obale je obranný vzor – umožňuje dekoratérovi pracovať na akejkoľvek funkcii bez ohľadu na podpis. Preskočte to a dostanete TypeError: wrapper() má 0 pozičných argumentov, ale boli dané 2 v momente, keď niekto ozdobí funkciu parametrami.

Oprava @functools.wraps

Jedna jemná chyba: po zdobení je „add.__name__“ „zabaliť“, nie „pridať“. Docstring a tipy na typ tiež zmiznú. Oprava je jeden import:

▶ PYTHONeditable · runs in your browser

Pravidlo: každý dekoratér, ktorý napíšete, by mal používať `@functools.wraps(fn)`. Stojí to jeden riadok a zabraňuje celej kategórii bolesti pri ladení (introspekcia, zariadenia pytest, formátovače protokolovania, pickle – všetky sa bez toho potichu prerušia).

Štyri dekorátory, ktoré uvidíte v každej kódovej základni

1. @vlastnosť — vypočítané atribúty

▶ PYTHONeditable · runs in your browser

@vlastnosť robí metódu volateľnou ako keby to bol atribút. Ideálne pre hodnoty odvodené len na čítanie. Pre cestu zápisu existuje aj @area.setter, ale 90 % použití @property je len na čítanie.

2. @staticmethod a @classmethod

▶ PYTHONeditable · runs in your browser

@classmethod dostane cls (samotnú triedu) a používa sa pre alternatívne konštruktory. @staticmethod neprináša nič zvláštne a je to obyčajná funkcia, ktorá náhodou žije v priestore názvov triedy.

3. @functools.cache — zapamätanie

▶ PYTHONeditable · runs in your browser

Jeden z najvýkonnejších dekoratérov stdlib. Automaticky zapamätá funkciu na základe jej argumentov. Vyžaduje, aby všetky argumenty boli hašovateľné (žiadne zoznamy / diktáty ako argumenty – použite n-tice).

4. @dataclasses.dataclass — eliminácia štandardných modelov

▶ PYTHONeditable · runs in your browser

@dataclass číta anotácie typu na úrovni triedy a automaticky generuje __init__, __repr__, __eq__ a (s frozen=True) __hash__. Je to najväčšie zlepšenie kvality života v Pythone 3.7+.

Písanie dekorátora „@retry“ (reálny príklad)

Dekoratér, ktorý pri zlyhaní zopakuje funkciu s exponenciálnym stiahnutím:

▶ PYTHONeditable · runs in your browser

Všimnite si tri vnorené funkcie: retry akceptuje konfiguračné argumenty a vráti decorator; decorator prijme funkciu a vráti wrapper; wrapper spustí cyklus opakovania. Tento trojvrstvový vzor vyzerá ako každý dekoratér s argumentmi – zapamätajte si tvar, nie konkrétny príklad.

Dekoratéri podľa triedy (zriedkavé, ale užitočné)

Dekoratér je ľubovoľný. Triedy s __call__ fungujú tiež:

▶ PYTHONeditable · runs in your browser

Použite, keď dekorátor potrebuje udržať stav, ktorý prežije jeden hovor (počítadlo, vyrovnávacia pamäť, vedro s limitom sadzby).

Bežné nástrahy

1. Zabudnutie na `@functools.wraps` — introspekcia sa ticho preruší.

2. Premenlivé predvolené argumenty v samotnom dekorátore – aj tu sa objavila klasická chyba def wrapper(x, cache=[]).

3. Zdobenie metód bez akceptovania `ja` — pamätajte, že ja je len pozičný argument; *args, **kwargs to chytí dobre.

4. Pri ukladaní na seba záleží: @a\n@b\ndef f() je f = a(b(f)). Čítať zásobníky zdola nahor.

Cvičte

Napíšte dekorátor @timing, ktorý vypíše, ako dlho trvá spustenie zabalenej funkcie, a potom ho aplikujte na funkciu, ktorá vypočíta sum(rozsah(10_000_000)). Celý dekoratér má 8 riadkov s functools.wraps + time.perf_counter.


Keď si osvojíte, že @x je f = x(f), dekorátory sa stanú jednou z najproduktívnejších funkcií Pythonu. Sú všade v skutočných kódových základniach: cesty Flask/FastAPI (@app.route), zariadenia pytestu (@pytest.fixture), zobrazenia Django (@požadované_prihlásenie), validátory Pydantic (@field_validator). Naučiť sa ich písať sami odomkne schopnosť čítať každý z nich.

Ďalší krok: [10 praktických lekcií pre dekoratérov] (/kurzy/senior) — vytvorte si @retry, @memoise, @rate_limit a @requires_auth od začiatku so skutočným Pythonom spusteným vo vašom prehliadači.

Chcete to vyskúšať?

15 lekcií zdarma po bezplatnej registrácii – žiadna karta. Otestujte platformu a potom sa rozhodnite.

Začnite zadarmo →

Or unlock every lesson

Pro — $12/mo, unlimited AI, cancel any time. Refund within 14 days worldwide.

See Pro plans →

Get one Python lesson + one career idea every Friday

No spam, no "buy our course now". Three bullets, every Friday. Unsubscribe with one click.