Vytvořte modul decorators.py
obsahující tři dekorátory delay
, call_info
a catch
.
Soubor decorators.py
nesmí obsahovat žádný jiný kód, než je kód dekorátoru. Případné testování provádějte v jiných souborech, které nebudete do repozitáře commitovat.
Vytvořte dekorátor @delay(seconds=X)
, který při zavolání obalené funkce zpomalí její vykonání o X
sekund. Výchozí doba zpomalení bez uvedení parametru seconds
bude 1 sekunda.
Zpomalení (uspání) je možné provést následovně:
import time
# uspí program na 3 sekundy
time.sleep(3)
Příklad použití:
@delay()
def my_sum(a, b):
return a + b
my_sum(2, b=3)
@delay()
def test_print():
return "Ahoj svete"
test_print()
@delay(seconds=2)
def my_sum(a, b):
return a + b
my_sum(2, b=3)
Vytvořte dekorátor @call_info
, který při zavolání obalené funkce vypíše na standardní výstup seznam argumentů (args
), seznam pojmenovaných argumentů (kwargs
), název funkce a výsledek v následujícím formátu. Zbytek funkce a její návratová hodnota funguje stejně.
Pro získání hodnoty argumentu a výsledku použijte funkci repr()
.
# vrátí reprezentaci hodnoty 2
repr(2)
# vrátí reprezentaci výsledku sum(2, 3)
repr(sum(2, 3))
Příklad použití:
@call_info
def my_sum(a, b):
return a + b
assert my_sum(6, 9) + 2 == 17
Na standardní výstup vypíše:
Calling: my_sum(6, 9)
Result: 15
@call_info
def my_sum(a, b):
return a + b
assert my_sum(2, b=3) + 2 == 7
Na standardní výstup vypíše:
Calling: my_sum(2, b=3)
Result: 5
@call_info
def test():
return 42
assert test() == 42
Na standardní výstup vypíše:
Calling: test()
Result: 42
@call_info
def test():
pass
assert test() == None
Na standardní výstup vypíše:
Calling: test()
Result: None
Vytvořte dekorátor @catch(*exceptions, error_value=None)
, který při zavolání obalené funkce zachytí zadané výjimky (exceptions). Pokud dojde k chybě, vrátí předem definovanou hodnotu (error_value). Pokud není zadaná žádná výjimka (v parametru exceptions
), dekorátor automaticky zachytí všechny výjimky pomocí obecné vyjímky Exception
. Pokud není specifikována návratová hodnota error_value
, funkce vrátí v případě chyby None
.
Dekorátor by měl fungovat tak, že:
- Zachytí uvedené výjimky nebo, pokud nejsou výjimky specifikovány, zachytí všechny výjimky.
- Pokud je výjimka zachycena, funkce místo toho vrátí hodnotu definovanou parametrem
error_value
. - Pokud nedojde k žádné výjimce, funkce se provede normálně a vrátí svůj výsledek.
@catch(TypeError, error_value="Type mismatch!")
def add(a, b):
return a + b
add("Hello, ", "world!") # vrátí "Hello, world!"
add(5, 10) # vrátí 15
add("Hello, ", 5) # vrátí "Type mismatch!"
@catch(ZeroDivisionError, TypeError, error_value="Division error!")
def safe_divide(a, b):
return a / b
safe_divide(4, 2) # vrátí 2.0
safe_divide(4, 0) # vrátí "Division error!"
safe_divide(4, "42") # vrátí "Division error!"
@catch(error_value="Something went wrong!")
def risky_operation():
raise ValueError("An error occurred")
risky_operation() # vrátí "Something went wrong!" (zachytí všechny výjimky)
Funkčnost řešení ověříte následujícím příkazem:
pytest tests.py