استفاده از functools در پایتون: مبانی و کاربردها

استفاده از functools در پایتون: مبانی و کاربردها

ماژول functools در پایتون مجموعه‌ای از ابزارهای بالاتر مرتبه را ارائه می‌دهد که برای کار با توابع و فراخوانی‌های تابع طراحی شده‌اند. این ماژول به شما امکان می‌دهد تا توابع را به عنوان آرگومان به سایر توابع ارسال کنید، توابع را به صورت جزئی اعمال کنید، و توابعی را ایجاد کنید که رفتار توابع دیگر را تغییر می‌دهند. در این مقاله، به بررسی مفاهیم کلیدی و کاربردهای عملی ماژول functools می‌پردازیم.

مقدمه‌ای بر توابع بالاتر مرتبه

توابع بالاتر مرتبه (Higher-Order Functions) توابعی هستند که می‌توانند توابع دیگر را به عنوان آرگومان دریافت کنند یا توابعی را به عنوان خروجی برگردانند. این مفهوم در برنامه‌نویسی تابعی بسیار مهم است و به شما امکان می‌دهد تا کدهای انعطاف‌پذیر و قابل استفاده مجدد بنویسید. پایتون به طور ذاتی از توابع بالاتر مرتبه پشتیبانی می‌کند و ماژول functools ابزارهایی را برای کارآمدتر کردن استفاده از آن‌ها فراهم می‌کند.

functools.partial: اعمال جزئی تابع

یکی از پرکاربردترین توابع در ماژول functools، تابع partial است. این تابع به شما امکان می‌دهد تا یک یا چند آرگومان را به یک تابع موجود ارائه دهید و یک تابع جدید ایجاد کنید که با آرگومان‌های ارائه شده و آرگومان‌های باقی‌مانده فراخوانی می‌شود. این کار به خصوص زمانی مفید است که شما نیاز دارید یک تابع را با آرگومان‌های پیش‌فرض فراخوانی کنید، اما می‌خواهید امکان تغییر برخی از آرگومان‌ها را نیز داشته باشید.

مثال:

def ضرب(x, y):
  return x * y

ضرب_در_دو = functools.partial(ضرب, 2)

print(ضرب_در_دو(5))  # خروجی: 10

در این مثال، تابع partial یک تابع جدید به نام ضرب_در_دو ایجاد می‌کند که آرگومان اول تابع ضرب را به مقدار 2 تنظیم می‌کند. سپس، می‌توانیم ضرب_در_دو را با یک آرگومان فراخوانی کنیم تا حاصل ضرب 2 در آن آرگومان را بدست آوریم.

functools.lru_cache: ذخیره‌سازی نتایج تابع

تابع lru_cache یک دکوراتور است که نتایج یک تابع را ذخیره می‌کند تا در صورت فراخوانی مجدد با همان آرگومان‌ها، نتیجه ذخیره شده به جای محاسبه مجدد برگردانده شود. این تکنیک به عنوان ذخیره‌سازی (Caching) شناخته می‌شود و می‌تواند به طور قابل توجهی عملکرد توابعی را که محاسبات پرهزینه‌ای انجام می‌دهند، بهبود بخشد.

مثال:

import functools

@functools.lru_cache(maxsize=None)
def فیبوناچی(n):
  if n < 2:
    return n
  return فیبوناچی(n-1) + فیبوناچی(n-2)

print(فیبوناچی(10))  # خروجی: 55

در این مثال، تابع lru_cache نتایج تابع فیبوناچی را ذخیره می‌کند. بنابراین، هنگامی که فیبوناچی(10) برای اولین بار فراخوانی می‌شود، نتیجه محاسبه می‌شود و ذخیره می‌شود. در صورت فراخوانی مجدد فیبوناچی(10)، نتیجه ذخیره شده به جای محاسبه مجدد برگردانده می‌شود. آرگومان maxsize حداکثر تعداد نتایج ذخیره شده را تعیین می‌کند. اگر maxsize برابر با None باشد، تمام نتایج ذخیره می‌شوند.

functools.wraps: حفظ اطلاعات تابع اصلی

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

مثال:

import functools

def دکوراتور(func):
  @functools.wraps(func)
  def wrapper(*args, **kwargs):
    print("قبل از فراخوانی تابع")
    result = func(*args, **kwargs)
    print("بعد از فراخوانی تابع")
    return result
  return wrapper

@دکوراتور
def سلام(name):
  """این تابع یک پیام سلام را چاپ می‌کند."""
  print(f"سلام، {name}!")

print(سلام.__name__)  # خروجی: سلام
print(سلام.__doc__)   # خروجی: این تابع یک پیام سلام را چاپ می‌کند.

در این مثال، تابع wraps اطلاعات تابع سلام را به تابع wrapper منتقل می‌کند. بنابراین، سلام.__name__ برابر با “سلام” و سلام.__doc__ برابر با مستندات تابع سلام است.

functools.reduce: کاهش یک دنباله به یک مقدار واحد

تابع reduce یک تابع را به صورت تکراری بر روی عناصر یک دنباله اعمال می‌کند تا یک مقدار واحد را بدست آورد. این تابع در پایتون 3 از ماژول functools به ماژول اصلی منتقل شده است.

مثال:

import functools

numbers = [1, 2, 3, 4, 5]

sum_of_numbers = functools.reduce(lambda x, y: x + y, numbers)

print(sum_of_numbers)  # خروجی: 15

در این مثال، تابع reduce تابع lambda را به صورت تکراری بر روی عناصر لیست numbers اعمال می‌کند تا مجموع آن‌ها را بدست آورد.

سایر توابع مفید در functools

علاوه بر توابعی که در بالا ذکر شد، ماژول functools توابع دیگری نیز ارائه می‌دهد که می‌توانند در موارد خاص مفید باشند:

  • functools.cmp_to_key: یک تابع مقایسه قدیمی را به یک تابع کلید تبدیل می‌کند.
  • functools.total_ordering: یک کلاس را به طور کامل مرتب می‌کند، اگر فقط یک روش مقایسه تعریف شده باشد.
  • functools.singledispatch: یک تابع را بر اساس نوع آرگومان اول آن، به توابع مختلف dispatch می‌کند.

نتیجه‌گیری

ماژول functools ابزارهای قدرتمندی را برای کار با توابع و فراخوانی‌های تابع در پایتون ارائه می‌دهد. با استفاده از این ماژول، می‌توانید کدهای انعطاف‌پذیر، قابل استفاده مجدد و کارآمدتری بنویسید. توابعی مانند partial، lru_cache و wraps به طور خاص در برنامه‌نویسی تابعی و ایجاد دکوراتورها بسیار مفید هستند. درک و استفاده از این ابزارها می‌تواند به شما در بهبود کیفیت و عملکرد کدهای پایتون کمک کند.

بدون دیدگاه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *