NOVINKA: Získej 40 hodin praktických dovedností s AI – ZDARMA ke každému akreditovanému kurzu!

Diskuze – Lekce 17 - Dekorátory v Pythonu

Zpět

Upozorňujeme, že diskuze pod našimi online kurzy jsou nemoderované a primárně slouží k získávání zpětné vazby pro budoucí vylepšení kurzů. Pro studenty našich rekvalifikačních kurzů nabízíme možnost přímého kontaktu s lektory a studijním referentem pro osobní konzultace a podporu v rámci jejich studia. Toto je exkluzivní služba, která zajišťuje kvalitní a cílenou pomoc v případě jakýchkoli dotazů nebo projektů.

Komentáře
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.

 
Odpovědět
4.7.2024 22:25
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
 
Odpovědět
6.8.2024 19:58
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)
 
Odpovědět
6.8.2024 21:14
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.

 
Odpovědět
6.8.2024 21:27
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.

 
Odpovědět
6.8.2024 21:31
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
 
Odpovědět
27.8.2024 23:44
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 :)

 
Odpovědět
29.8.2024 14:40
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 :)

 
Odpovědět
29.8.2024 14:49
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.

 
Odpovědět
13.11.2024 20:43
Avatar
Dalibor Rokyta:23. ledna 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.

 
Odpovědět
23. ledna 11:20
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 23.