మాడ్యూల్ పాఠాలు (4/4)
డెకరేటర్లు: ఫంక్షన్లను సవరించే విధులు
ఒక డెకరేటర్ అనేది మరొక ఫంక్షన్ని తీసుకొని aని తిరిగి ఇచ్చే ఒక ఫంక్షన్ దాని "అలంకరించిన" వెర్షన్. ప్రవర్తనను జోడించడానికి ఇది ఒక శక్తివంతమైన మార్గం శరీరాన్ని తాకకుండా (లాగింగ్, టైమింగ్, కాషింగ్, మళ్లీ ప్రయత్నించడం, ధ్రువీకరణ). అసలు విధి.
విలువలుగా విధులు
పైథాన్లో, విధులు వస్తువులు: మీరు వాటిని పాస్ చేయవచ్చు, వాటిని తిరిగి ఇవ్వవచ్చు, వాటిని కేటాయించవచ్చు.
def saluta():
print("ciao")
f = saluta # NIENTE parentesi: assegno la funzione
f() # 'ciao'కనీస డెకరేటర్
def log(func):
def wrapper(*args, **kwargs):
print(f"chiamo {func.__name__}")
risultato = func(*args, **kwargs)
print(f"ho finito {func.__name__}")
return risultato
return wrapper
def somma(a, b):
return a + b
somma = log(somma) # ora somma è "wrapper"
somma(2, 3)
# chiamo somma
# ho finito somma
# 5@decorator సింటాక్స్
somma = log(somma) అసైన్మెంట్ @తో మరింత సొగసైనదిగా వ్రాయబడింది:
@log
def somma(a, b):
return a + bఇది సరిగ్గా అదే విషయం. నిర్వచనం పైన @log దీనికి సమానం:
"ఈ ఫంక్షన్ నిర్వచించబడిన వెంటనే, దానిని log(function)తో భర్తీ చేయండి".
*args, **kwargs: ఏదైనా సంతకాన్ని ఆమోదించండి
def wrapper(*args, **kwargs):
return func(*args, **kwargs)*args స్థాన ఆర్గ్యుమెంట్లను, **kwargs కీవర్డ్ ఆర్గ్యుమెంట్లను సేకరిస్తుంది. వారు అనుమతించారు
మీరు ఏదైనా ఫంక్షన్తో పని చేసే రేపర్లను వ్రాస్తారు.
functools.wraps: మెటాడేటాను భద్రపరచండి
wraps లేకుండా, అలంకరించబడిన ఫంక్షన్ __name__, __doc__, సూచనలు:
from functools import wraps
def log(func):
@wraps(func)
def wrapper(*args, **kwargs):
...
return func(*args, **kwargs)
return wrapperఉదాహరణ: @timeit
from functools import wraps
import time
def timeit(func):
@wraps(func)
def wrapper(*args, **kwargs):
t0 = time.perf_counter()
risultato = func(*args, **kwargs)
dt = time.perf_counter() - t0
print(f"{func.__name__} ha impiegato {dt*1000:.2f} ms")
return risultato
return wrapper
@timeit
def somma_grande():
return sum(range(10**6))
somma_grande()stdlib నుండి డెకరేటర్లు
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n < 2: return n
return fib(n - 1) + fib(n - 2)
fib(100) # istantaneo grazie alla cache@lru_cache— స్వచ్ఛమైన ఫంక్షన్ ఫలితాలను జ్ఞాపకం చేస్తుంది.@property— ఒక పద్ధతిని లక్షణంగా బహిర్గతం చేస్తుంది (OOP మాడ్యూల్లో కనిపిస్తుంది).@staticmethod,@classmethod—selfఎలా ఆమోదించబడుతుందో మార్చండి.
వాదనలతో అలంకారకులు
డెకరేటర్లు కూడా వాదనలను అంగీకరించవచ్చు. దీన్ని అమలు చేయడానికి, మీరు తప్పనిసరిగా మూడు స్థాయిల సమూహ ఫంక్షన్లను వ్రాయాలి: బయటి ఫంక్షన్ డెకరేటర్ ఆర్గ్యుమెంట్లను అందుకుంటుంది, మధ్య ఫంక్షన్ అలంకరించబడిన ఫంక్షన్ను అందుకుంటుంది మరియు లోపలి ఫంక్షన్ (wrapper) కాల్ల సమయంలో అలంకరించబడిన ఫంక్షన్కు పంపబడిన వాస్తవ ఆర్గ్యుమెంట్లను అందుకుంటుంది.
మీరే ప్రయత్నించండి
డెకరేటర్ `డబుల్_ఫలితం`ని వ్రాయండి, అది అలంకరించబడిన ఫంక్షన్ని పిలిచి దాని ఫలితాన్ని అందిస్తుంది * 2. దాన్ని x + 1ని అందించే ఫంక్షన్ `f(x)`కి వర్తింపజేయండి. `f(10)`ని మూల్యాంకనం చేయండి.
సూచనను చూపించు
రేపర్ ఫంక్ని పిలుస్తుంది మరియు ఫలితాన్ని 2తో గుణించబడుతుంది.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
వ్యాయామం సమీక్షించండి
పునరావృత fib(n) ఫంక్షన్ని వేగవంతం చేయడానికి functools.lru_cacheని ఉపయోగించండి. fib(30)ని గణించి, `r`కి కేటాయించండి. `r`ని మూల్యాంకనం చేయండి.
సూచనను చూపించు
@lru_cache(maxsize=nene) డెఫ్ పైన.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
అదనపు సవాలు
Define a decorator `double_result` that doubles (multiplies by 2) the return value of the decorated function. Apply the decorator to the function `def sum_nums(a, b): return a + b`. Finally, evaluate `sum_nums(3, 4)`.
సూచనను చూపించు
రేపర్ ఫంక్ (*ఆర్గ్స్, **క్వార్గ్స్) అని పిలుస్తుంది మరియు ఫలితాన్ని 2తో గుణిస్తుంది.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది