دکوراتورها در پایتون

تابع به‌عنوان آرگومان، closure، @decorator و کاربردهای آن

دکوراتور چیست؟

دکوراتور (Decorator) تابعی است که تابع دیگر را می‌گیرد و رفتار آن را تغییر/گسترش می‌دهد، بدون اینکه کد تابع اصلی را تغییر دهد.

توابع شهروند درجه‌یک

در پایتون، توابع مثل سایر مقادیر هستند — می‌توان آن‌ها را در متغیر ذخیره یا به‌عنوان آرگومان پاس داد:

def greet():
    return "سلام"

# ذخیره در متغیر
say_hello = greet
print(say_hello())  # سلام

# تابع به‌عنوان آرگومان
def call_func(f):
    return f()

print(call_func(greet))  # سلام

تابع داخل تابع

def outer():
    def inner():
        print("داخلی")
    inner()

outer()

تابع برگرداندن تابع

def make_greeter(name):
    def greeter():
        return f"سلام {name}!"
    return greeter

greet_ali = make_greeter("علی")
print(greet_ali())  # سلام علی!

دکوراتور ساده

def uppercase_decorator(func):
    def wrapper():
        result = func()
        return result.upper()
    return wrapper

@uppercase_decorator
def greet():
    return "hello world"

print(greet())  # HELLO WORLD

دکوراتور با آرگومان

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def say_hi(name):
    print(f"سلام {name}!")

say_hi("علی")  # ۳ بار چاپ می‌شود

دکوراتور زمان‌سنجی

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__}: {end - start:.4f} ثانیه")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)
    return "تمام!"

slow_function()  # slow_function: 1.0012 ثانیه

functools.wraps

برای حفظ اطلاعات تابع اصلی:

from functools import wraps

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

خلاصه

مفهومتوضیح
دکوراتورتابعی که تابع دیگر را تغییر می‌دهد
@nameسینتکس دکوراتور
wrapperتابع درونی دکوراتور
*args, **kwargsبرای هر امضای تابع

این مبحث بخشی از دوره آموزش کامل پایتون است.

ابزارهای مرتبط