முக்கிய உள்ளடக்கத்திற்குச் செல்லவும்
தொகுதி 9 · பாடம் 4 இன் 4பாடத்திட்டத்தில் 36/36~14 min
தொகுதி பாடங்கள் (4/4)

அலங்கரிப்பவர்கள்: செயல்பாடுகளை மாற்றியமைக்கும் செயல்பாடுகள்

ஒரு அலங்கரிப்பான் என்பது மற்றொரு செயல்பாட்டை எடுத்து ஒரு செயல்பாட்டை வழங்கும் அதன் "அலங்கரிக்கப்பட்ட" பதிப்பு. நடத்தை சேர்க்க இது ஒரு சக்திவாய்ந்த வழியாகும் (லாக்கிங், டைமிங், கேச்சிங், மீண்டும் முயற்சி, சரிபார்த்தல்) உடலைத் தொடாமல் அசல் செயல்பாடு.

மதிப்புகளாக செயல்படுகிறது

பைத்தானில், செயல்பாடுகள் பொருள்கள்: நீங்கள் அவற்றை அனுப்பலாம், திருப்பி அனுப்பலாம், ஒதுக்கலாம்.

Python
def saluta():
    print("ciao")

f = saluta   # NIENTE parentesi: assegno la funzione
f()          # 'ciao'

ஒரு குறைந்தபட்ச அலங்கரிப்பாளர்

Python
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) பணியானது @ உடன் மிகவும் நேர்த்தியாக எழுதப்பட்டுள்ளது:

Python
@log
def somma(a, b):
    return a + b

இது சரியாக அதே விஷயம். வரையறைக்கு மேலே @log இதற்குச் சமம்: "இந்த செயல்பாடு வரையறுக்கப்பட்டவுடன், அதை log(function) என மாற்றவும்".

*args, **kwargs: எந்த கையொப்பத்தையும் ஏற்கவும்

Python
def wrapper(*args, **kwargs):
    return func(*args, **kwargs)

*args நிலை வாதங்களை சேகரிக்கிறது, **kwargs முக்கிய வாதங்கள். அவர்கள் அனுமதித்தனர் நீங்கள் எந்த செயல்பாட்டிலும் வேலை செய்யும் ரேப்பர்களை எழுதுகிறீர்கள்.

functools.wraps: மெட்டாடேட்டாவைப் பாதுகாத்தல்

wraps இல்லாமல், அலங்கரிக்கப்பட்ட செயல்பாடு __name__, __doc__, குறிப்புகள்:

Python
from functools import wraps

def log(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        ...
        return func(*args, **kwargs)
    return wrapper

எடுத்துக்காட்டு: @timeit

Python
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 இலிருந்து அலங்கரிப்பவர்கள்

Python
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) அழைப்புகளின் போது அலங்கரிக்கப்பட்ட செயல்பாட்டிற்கு அனுப்பப்பட்ட உண்மையான வாதங்களைப் பெறுகிறது.

நீங்களே முயற்சி செய்து பாருங்கள்

உடற்பயிற்சி#python.m9.l4.e1
முயற்சிகள்: 0ஏற்றுகிறது…

அலங்கரிக்கப்பட்ட செயல்பாட்டிற்கு அழைப்பு விடுத்து அதன் முடிவைத் தரும் டெக்கரேட்டரை `இரட்டை_முடிவு` எழுதவும் * 2. அதை x + 1 ஐ வழங்கும் `f(x)` செயல்பாட்டிற்குப் பயன்படுத்தவும். `f(10)` என்பதை மதிப்பிடவும்.

எடிட்டரை ஏற்றுகிறது…
குறிப்பைக் காட்டு

ரேப்பர் ஃபங்க் என்று அழைக்கிறது மற்றும் முடிவை 2 ஆல் பெருக்குகிறது.

3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்

மதிப்பாய்வு பயிற்சி

உடற்பயிற்சி#python.m9.l4.e2
முயற்சிகள்: 0ஏற்றுகிறது…

சுழல்நிலை fib(n) செயல்பாட்டை விரைவுபடுத்த functools.lru_cache ஐப் பயன்படுத்தவும். fib(30)ஐக் கணக்கிட்டு `r`க்கு ஒதுக்கவும். `r` மதிப்பிடவும்.

எடிட்டரை ஏற்றுகிறது…
குறிப்பைக் காட்டு

@lru_cache(maxsize=None) டெஃபிற்கு மேலே.

3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்

கூடுதல் சவால்

உடற்பயிற்சி#python.m9.l4.e3
முயற்சிகள்: 0ஏற்றுகிறது…

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)`.

எடிட்டரை ஏற்றுகிறது…
குறிப்பைக் காட்டு

ரேப்பர் func(*args, **kwargs) என அழைக்கிறது மற்றும் முடிவை 2 ஆல் பெருக்குகிறது.

3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்