خانه / آموزش‌ها / آموزش ماژول Functools در پایتون

آموزش ماژول Functools در پایتون

🐍 HomeOfPython
|
📅 1404/10/22

سطح مقدماتی (Beginner Level)

ماژول functools یکی از کتابخانه‌های استاندارد و بسیار قدرتمند پایتون است که ابزارهایی برای کار با توابع (Functions) و اشیاء قابل فراخوانی (Callables) فراهم می‌کند. این ماژول برای برنامه‌نویسی تابعی (Functional Programming) و بهینه‌سازی کد بسیار حیاتی است.

در سطح مقدماتی با مفاهیم پایه‌ای مثل partial و جایگاه reduce آشنا می‌شویم.

۱. تابع Partial (ثابت کردن آرگومان‌ها)

گاهی اوقات تابعی دارید که چندین آرگومان می‌گیرد، اما می‌خواهید نسخه جدیدی از آن بسازید که برخی از آرگومان‌هایش از قبل مقداردهی (Fixed) شده باشند. تابع partial این کار را برای شما انجام می‌دهد.

این کار باعث می‌شود کد خواناتر شود و نیاز به تکرار آرگومان‌های تکراری نباشد.

Python

۲. تابع Reduce (کاهش لیست به یک مقدار)

اگرچه map و filter توابع داخلی (Built-in) هستند، اما reduce در پایتون ۳ به ماژول functools منتقل شده است. این تابع یک لیست را پیمایش کرده و با اعمال یک تابع روی اجزای آن، در نهایت یک خروجی واحد تولید می‌کند (مثل محاسبه مجموع یا ضرب کل اعضا).

Python
python
# Example 3 (Static): Lambda syntax for reduce (Snippet)
from functools import reduce

# Compact version using lambda
total = reduce(lambda a, b: a + b, [10, 20, 30, 40])
# total will be 100

سطح پیشرفته (Professional Level)

در سطح حرفه‌ای، functools ابزارهایی برای بهینه‌سازی عملکرد (Performance)، مدیریت متادیتای دکوریتورها و ایجاد توابع جنریک (Generic Functions) ارائه می‌دهد. تسلط بر این بخش‌ها شما را از یک کدنویس معمولی به یک مهندس نرم‌افزار پایتون تبدیل می‌کند.

۱. کش‌سازی با lru_cache@ (Memoization)

یکی از بهترین قابلیت‌های functools دکوریتور lru_cache (Least Recently Used Cache) است. این ابزار خروجی توابع سنگین را بر اساس ورودی‌هایشان ذخیره می‌کند. اگر تابع مجدداً با همان ورودی‌ها صدا زده شود، پایتون آن را اجرا نمی‌کند بلکه نتیجه ذخیره شده را برمی‌گرداند.

این تکنیک برای توابع بازگشتی (مثل فیبوناچی) یا عملیات I/O سنگین معجزه می‌کند.

نمودار عملکرد کش

Python

۲. حفظ اصالت تابع با wraps@

وقتی خودتان دکوریتور (Decorator) می‌نویسید، تابع اصلی درون یک تابع پوششی (Wrapper) قرار می‌گیرد. این کار باعث می‌شود نام تابع (__name__) و توضیحات آن (__doc__) از بین برود و با نام Wrapper جایگزین شود. دکوریتور wraps@ این مشکل را حل می‌کند و متادیتای تابع اصلی را به تابع جدید کپی می‌کند. این برای دیباگ کردن و تولید مستندات حیاتی است.

Python

۳. توابع چندریختی با singledispatch@

پایتون به صورت پیش‌فرض از Overloading (تعریف چند تابع هم‌نام با ورودی‌های مختلف) پشتیبانی نمی‌کند. اما singledispatch به شما اجازه می‌دهد رفتارهای متفاوتی برای یک تابع بر اساس نوع (Type) اولین آرگومان ورودی تعریف کنید.

Python

۴. مقایسه آسان کلاس‌ها با total_ordering@

برای اینکه اشیاء یک کلاس قابل مقایسه باشند (مثلاً بتوانید آنها را sort کنید)، باید متدهای __lt__, __le__, __gt__, __ge__ را پیاده‌سازی کنید. دکوریتور total_ordering کار را راحت می‌کند: شما فقط یکی از متدهای مقایسه و متد __eq__ را تعریف می‌کنید، و پایتون بقیه را خودکار می‌سازد.

python
# Advanced Example 4 (Snippet): Simplifying class comparisons
from functools import total_ordering

@total_ordering
class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade

    def __eq__(self, other):
        return self.grade == other.grade

    def __lt__(self, other):
        # تعریف فقط همین یک متد کافیست تا <, <=, >, >= همگی کار کنند
        return self.grade < other.grade

s1 = Student("Ali", 18)
s2 = Student("Reza", 15)

# print(s1 > s2)  # True (Generated automatically)