Mikuláš je tu! Získaj 90 % extra kreditov ZADARMO s promo kódom CERTIK90 pri nákupe od 1 199 kreditov. Len do nedele 7. 12. 2025! Zisti viac:
NOVINKA: Najžiadanejšie rekvalifikačné kurzy teraz s 50% zľavou + kurz AI ZADARMO. Nečakaj, táto ponuka dlho nevydrží! Zisti viac:

Diskusia – 17. diel - Dekorátory v Pythone

Späť

Upozorňujeme, že diskusie pod našimi online kurzami sú nemoderované a primárne slúžia na získavanie spätnej väzby pre budúce vylepšenie kurzov. Pre študentov našich rekvalifikačných kurzov ponúkame možnosť priameho kontaktu s lektormi a študijným referentom pre osobné konzultácie a podporu v rámci ich štúdia. Toto je exkluzívna služba, ktorá zaisťuje kvalitnú a cielenú pomoc v prípade akýchkoľvek otázok alebo projektov.

Komentáre
Posledné komentáre sú na spodnej časti poslednej stránky.
Avatar
Petr Čeněk
Člen
Avatar
Petr Čeněk:4.7.2024 22:25

Preferoval bych lepší vysvětlení. Z textu a uvedených příkladů velmi těžko pochopitelné. Bez dalších příkladů a tutoriálu na YouTube bych to asi těžko pochopil.

Avatar
honza394
Člen
Avatar
honza394:6.8.2024 19:58

Ahoj, v kódu je pořadí dekorátorů obráceně, než je vysvětleno v textu.
Funkci:

vypocet_objemu_krychle(zmer_cas(validuj_vstup(obsah_ctverce)))(3)

odpovídá pořadí dekorátorů:

@vypocet_objemu_krychle
@zmer_cas
@validuj_vstup
Avatar
honza394
Člen
Avatar
honza394:6.8.2024 21:14

Pro názornost jsem přidal print() do každé funkce. Pro ověření "stejnosti" si jen vyměňte komentáře u dekorátorů a volání funkcí na konci.

import time
def vypocet_objemu_krychle(func):
    print("počítám objem")
    def vypocet_objemu_a_obsahu(*args, **kwargs):
        obsah = func(*args, **kwargs)
        objem = obsah * args[0]
        print(f"Obsah čtverce se stranou {args[0]} je: {obsah}")
        print(f"Objem krychle se stranou {args[0]} je: {objem}")
        print(f"args: {args}")
        print(f"kwargs: {kwargs}")
        return obsah

    return vypocet_objemu_a_obsahu

def validuj_vstup(func):
    print("validuji vstup")
    def over_data(*args, **kwargs):
        if any(arg <= 0 for arg in args):
            print("Varování: Všechny argumenty musí být kladné a nenulové.")
        return func(*args, **kwargs)


    return over_data

def zmer_cas(func):
    print("měřím čas")
    def zmer_a_vypis_cas(*args, **kwargs):
        zacatek = time.time()
        vysledek = func(*args, **kwargs)
        konec = time.time()
        print(f"Čas běhu funkce obsah_ctverce(): {konec - zacatek:.5f} sekund.")
        return vysledek
    return zmer_a_vypis_cas


# @vypocet_objemu_krychle
# @zmer_cas
# @validuj_vstup
def obsah_ctverce(a):
    print("počítám obsah")
    time.sleep(1)
    return a**2

vypocet_objemu_krychle(zmer_cas(validuj_vstup(obsah_ctverce)))(3)
# obsah_ctverce(3)
Avatar
honza394
Člen
Avatar
honza394:6.8.2024 21:27

Téma Vícenásobné dekorování je zajímavé, vysvětlení matoucí. Pod nadpisem je vysvětleno správně.
V ukázkovém kódu jsou dekorátory v opačném pořadí:
@validuj_vstup @zmer_cas @vypocet_obje­mu_krychle.
To neodpovídá vysvětlení pod kódem, že "Prvním dekorátorem, který se aplikuje, je @validuj_vstup, ... poté @zmer_cas, nakonec @vypocet_obje­mu_krychle...
Chybné a matoucí. Prosím opravit.

Avatar
honza394
Člen
Avatar
honza394:6.8.2024 21:31

Hodnocení článku: Vícenásobné dekorátory (pořadí) vysvětleny chybně, viz mé komentáře v diskuzi. Prosím o opravu.

Avatar
Tomáš Jícha:27.8.2024 23:44

Vícenásobné dekorování

zdrojový kód uvádí:
...
@validuj_vstup
@zmer_cas
@vypocet_obje­mu_krychle
def obsah_ctverce(a):
...

Popis uvádí přesně opačné pořadí.

Nesprávný popis začíná:
"Prvním dekorátorem, který se aplikuje, je @validuj_vstup, který obaluje funkci obsah_ctverce().

  • nesprávné vysvětlení pořadí se táhne až do konce kapitoly
Avatar
Tomáš Jícha:29.8.2024 14:40

Uvedu zde zdroj pro lepší výklad:

# Decorators in Python
# - https://www.geeksforgeeks.org/…s-in-python/

# Chaining Decorators ( Řetězové dekorátory )
# code for testing decorator chaining

def decor1(func):
def inner():
x = func() # 20 # 10 - IN
return x * x # 400 # 100 - OUT
return inner

def decor(func):
def inner():
x = func() # 10 # 100 - IN
return 2 * x # 20 # 200 - OUT
return inner

@decor1 # 20 - IN @decor1
@decor # 10 - IN @decor
def num():
return 10

@decor # 100 - IN @decor
@decor1 # 10 - IN @decor1
def num2():
return 10

print(num()) # 400
print(num2()) # 200

Stačí se trochu pozastavit a uvidíte, že anglický jazyk není ani potřeba :)

Avatar
Tomáš Jícha:29.8.2024 14:49

Uvedu zde zdroj pro lepší výklad:

Decorators in Python

Chaining Decorators ( Řetězové dekorátory )

# code for testing decorator chaining
def decor1(func):
    def inner():
        x = func()          # 20            # 10           - IN
        return x * x        # 400           # 100          - OUT
    return inner

def decor(func):
    def inner():
        x = func()          # 10            # 100           - IN
        return 2 * x        # 20            # 200           - OUT
    return inner

@decor1     # 20    - IN    @decor1
@decor      # 10    - IN    @decor
def num():
    return 10

@decor      # 100   - IN    @decor
@decor1     # 10    - IN    @decor1
def num2():
    return 10

print(num())                # 400
print(num2())                               # 200

Stačí se trochu pozastavit a uvidíte, že anglický jazyk není ani potřeba :)

Avatar
Martin Jílek:13.11.2024 20:43

dostala mě matoucí věta "Poslední dekorátor je ten, který se
nachází nejvýše." - sedělo by mně spíše příslovce "nejdále". Z kontextu článku dále to je ale jasné, jak to s pořadím dekorátorů je.

Avatar
Dalibor Rokyta:23. januára 11:20

Jak je zmíněno v komentářích, věřím, že jde o zajímavé téma, ale vysvětlení opět nedostatečné + obsahuje chyby v kódu.

Posledné komentáre sú na spodnej časti poslednej stránky.
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zobrazené 10 správy z 29.