دوره H برنامه نویسی پایتون
فصل پنجم: برنامه نویسی تابع گرا (Functional Programming)
درس اول: توابع لامبدا (Lambda) در پایتون
قبل از اینکه به روش تعریف توابع بهصورت لامبدا بپردازیم، اجازه دهید کمی با برنامه نویسی تابعگرا آشنا شویم.
برنامهنویسی تابعگرا
برنامهنویسی تابعگرا، سبکی از برنامهنویسی است؛ که (همانطور که از نامش پیداست)، بر پایهی توابع استوار میباشد.
بخش اصلی برنامهنویسی تابعگرا، توابع مرتبهی بالا است؛ و ما این ایده را بهطور خلاصه، در دروس قبلی بهعنوان توابع آبجکتی دیدیم. توابع مرتبهی بالاتر، توابع دیگری را به عنوان آرگومان دریافت کرده و یا اینکه، توابع دیگری را را بهعنوان خروجی برمیگردانند!
به مثال زیر دقت کنید:
1 2 3 4 5 6 7 |
def apply_twice(func, arg): return func(func(arg)) def add_five(x): return x + 5 print(apply_twice(add_five, 10)) |
خروجی:
1 2 3 |
>>> 20 >>> |
در اینجا تابع apply_twice، یک تابع دیگری را به عنوان ورودی دریافت میکند؛ که نام آن را func قرار دادیم؛ سپس این تابع دریافت شده را در داخل خود، دوبار فراخوانی میکند؛ که یک بار، خروجی آن را برای ورودی جدیدش استفاده کرده است. 🙂
توابع خالص (Pure)
هدف از برنامهنویسی تابعگرا، نوشتن توابع خالص است! توابع خالص، هیچ تاثیر جانبی نداشته و فقط مقداری را با توجه به آرگومانهای دریافتی برمیگردانند. در ادامه، مثالی از یک تابع خالص و ناخالص را داریم.
مثال تابع خالص:
1 2 3 |
def pure_function(x, y): temp = x + 2*y return temp / (2*x + y) |
مثال تابع ناخالص:
1 2 3 4 |
some_list = [] def impure(arg): some_list.append(arg) |
این تابع خالص نیست، چراکه برروی یک متغیر به نام some_list در بیرون از خود تاثیر میگذارد. (همان اثرات جانبی که در بالا گفته شد!)
استفاده از توابع خالص، مزایا و معایبی دارد. که از مزایای آنها:
- تست، استدلال و درک آنها راحتتر است.
- کارآمدترند.
- به راحتی میتوانند بهصورت موازی (parallel) اجرا شوند.
اما عیب اصلی در اینکه فقط از توابع خالص استفاده کنیم، این است که آنها عمدتا کارهای سادهی I/O را پیچیدهتر میکنند، چرا که به نظر میرسد این کار بهطور ذاتی، به اثرات جانبی نیاز دارد. همچنین نوشتن این توابع در برخی شرایط دشوارتر است.
لامبداها (Lambdas)
ایجاد یک تابع بهطور معمول و با استفاده از def، باعث میشود تا آن تابع بهصورت خودکار به یک متغیری نسبت داده شود؛ این کار با ایجاد اشیاء دیگر – مانند رشتهها و اعداد – متفاوت است؛ چراکه آنها میتوانند همینطور در هوا تعریف شده و به هیچ متغیری نسبت داده نشوند!
اما همین کار با توابع نیز امکانپذیر است! البته توابعی که با سینتکس لامبدا (Lambda) تعریف میشوند؛ و این توابع به توابع ناشناس (anonymous) نیز معروفند. این روش معمولا موقع ارسال یک تابع بهعنوان آرگومان ورودی به یک تابع دیگر، مورد استفاده قرار میگیرد. به مثال زیر دقت کنید:
1 2 3 4 |
def my_func(f, arg): return f(arg) my_func(lambda x: 2*x*x, 5) |
تابع my_func قرار است یک ورودی به نام f دریافت کند؛ که بایستی از نوع تابع باشد؛ و سپس آن را در بدنهی خود فراخوانی کرده و نتیجهاش را برمیگرداند. حالا موقع صدا زدن my_func، یک تابع بهصورت لامبدا ایجاد کردهایم. بدین صورت که ابتدا کلمهی کلیدی lambda را نوشته و سپس یک ورودی به نام x برای آن مشخص کرده و بدنهاش را نوشتهایم! بدنهی تابع بعد از دونقطه نوشته شده است؛ و حاصل آن بهصورت خودکار return میشود.
توابع لامبدا همانند توابع نامی (که با def تعریف میشوند) قدرتمند نیستند. آنها فقط میتوانند کارهایی انجام دهند که نیاز به یک بیان واحد دارند (معمولا معادل یک خط کد). برای مثال:
1 2 3 4 5 6 7 |
#named function def polynomial(x): return x**2 + 5*x + 4 print(polynomial(-4)) #lambda print((lambda x: x**2 + 5*x + 4) (-4)) |
خروجی:
1 2 3 4 |
>>> 0 0 >>> |
تابع polynomial که با def تعریف شده است، یک ورودی دریافت کرده و عملیات ریاضی بر روی آن انجام میدهد؛ سپس خروجی را برمیگرداند. در ادامه آن را با مقدار -4 فراخوانی و چاپ کردهایم که نتیجه 0 شده است. سپس همین تابع را بصورت لامبدا نوشتیم! نیازی به return نیست و محاسبه خود به خود برمیگردد! سپس درجا همین لامبدا را پس از تعریف، با مقدار -4 فراخوانی و خروجی را چاپ کردیم. بنابراین این تابع لامبدا، همینطور در هوا تعریف شده و به متغیری نسبت داده نشده است.
سلام آقای اکبر زاده.خسته نباشید
مطالب دوره واقعا عالی بودن و یک دید درست نسبت به مفاهیم به ما دادید
خواستم تقاضا کنم که دوره رو تکمیل کنید.واقعا حیفه این دوره بسیار فشرده با کیفیت بالا به اتمام نرسه
من زبان پایتون رو کامل آموزش دیدم و از مطالبتون برای مرور دارم استفاده میکنم که واقعا بدردم خوردن
منتظره درسها و فصلهای بعدی هستیم
سلام دوست من. نظر لطفتونه.
چشم حتما یه تایمی برای تکمیل دوره در نظر میگیرم. 🙂
درس بعدی هم بهزودی اضافه میشه…