پرسش

تابع functools.wraps در پایتون چه کاری انجام می‌دهد؟

What does functools.wraps do?

توی پایتون، از دکوراتور @functools.wraps استفاده می‌کنن ولی دقیق نمی‌دونم کارش چیه؟ دکوراتور چی کار می‌کنه و کجا باید ازش استفاده کنم؟

1403/06/06
پاسخ
رضا دولتی عاشق برنامه نویسی و هوش مصنوعی!
بیوگرافی رضا دولتی

@functools.wraps در پایتون یک دکوراتور هست که وقتی یک تابع رو دکوره (تزئین) می‌کنیم، استفاده می‌شه. این دکوراتور در واقع باعث می‌شه که تابع دکوره شده (تابعی که دکوراتور روش اعمال شده) مشخصات خودش مثل نام، داک‌استرینگ، و اطلاعات متا دیگه رو از تابع اصلی حفظ کنه.

فرض کن یه دکوراتور ساختی که یه کاری رو با یه تابع انجام می‌ده. اگر از @functools.wraps استفاده نکنی، تابع دکوره شده مشخصات اصلی خودش رو از دست می‌ده و وقتی بهش مثلا __name__ یا __doc__ رو می‌زنی، اطلاعات تابع اصلی رو بهت نمی‌ده. @functools.wraps کمک می‌کنه که این مشخصات دست‌نخورده بمونه.

یه نمونه کد برای درک بهترش:

import functools
def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        # Do something before the function
        print(f"Calling function {func.__name__}")
        return func(*args, **kwargs)
    return wrapper
@my_decorator
def say_hello():
    """This function says hello."""
    print("Hello!")
say_hello()
print(say_hello.__name__)  # Outputs: say_hello
print(say_hello.__doc__)   # Outputs: This function says hello.

my_decorator یه دکوراتور ساده است که فقط نام تابع رو قبل از اجرای تابع چاپ می‌کنه. اگر @functools.wraps رو استفاده نمی‌کردیم، بعد از دکور کردن، say_hello.__name__ مقدار wrapper رو برمی‌گردوند و __doc__ هم خالی می‌بود. ولی به لطف @functools.wraps، تابع say_hello همچنان نام و داک‌استرینگ اصلی خودش رو حفظ کرده.

این دکوراتور زمانی که می‌خوای یک تابع رو دکوره کنی و همچنان مشخصات اصلی اون تابع حفظ بشه، خیلی کاربرد داره.

پاسخ: 1403/06/06
آخرین آپدیت: 1403/08/12