متن خبر

توابع درجه یک، توابع درجه بالاتر و بسته شدن در پایتون – با مثال کد توضیح داده شده است

توابع درجه یک، توابع درجه بالاتر و بسته شدن در پایتون – با مثال کد توضیح داده شده است

شناسهٔ خبر: 567925 -




در برنامه نویسی مدرن، درک مفاهیمی مانند توابع درجه یک، توابع درجه بالاتر و بسته شدن مهم است. این ایده ها به ما کمک می کند تا کدی انعطاف پذیر و کارآمد بنویسیم. آنها همچنین بلوک های سازنده بسیاری از تکنیک های کدنویسی پیشرفته هستند.

توابع درجه یک و توابع درجه بالاتر به ما این امکان را می دهند که توابع را به عنوان متغیر در نظر بگیریم و کد ما را قدرتمندتر و قابل استفاده مجدد می کند. بسته شدن این کار را با اجازه دادن به توابع برای به خاطر سپردن متغیرها از محدوده خود یک قدم فراتر می برد.

این آموزش به این مفاهیم می پردازد و نحوه ارتباط آنها را با مثال های کدگذاری عملی برای نشان دادن استفاده از آنها توضیح می دهد.

فهرست مطالب

    توابع درجه یک
    - اختصاص توابع به متغیرها
    - عبور توابع به عنوان آرگومان
    - برگرداندن توابع از سایر توابع

    توابع مرتبه بالاتر
    - توابع لامبدا
    - تابع مرتبه بالاتر که تابعی را به عنوان آرگومان می گیرد
    - تابع مرتبه بالاتر که عملکرد دیگری را برمی گرداند

    بسته شدن
    بستن پایه (عملکرد تودرتوی پایه با اجرای فوری)
    - برگرداندن عملکرد داخلی
    - استفاده از بسته شدن با پارامترها

    برنامه های کاربردی در دنیای واقعی

    نتیجه

برای درک کامل بسته‌ها، ابتدا باید مفاهیم توابع درجه یک و توابع درجه بالاتر را درک کنید. این مفاهیم سنگ بنای بسیاری از الگوهای برنامه نویسی پیشرفته هستند و برای عملکرد بسته ها اساسی هستند. بیایید به این مفاهیم و چگونگی ارتباط آنها بپردازیم.

توابع درجه یک

در برنامه نویسی، اگر زبانی با توابع به عنوان شهروندان درجه یک رفتار کند، گفته می شود که دارای توابع درجه یک است. این بدان معنی است که توابع در چنین زبانی می توانند:

    به متغیرها اختصاص داده شده است

    به عنوان آرگومان به توابع دیگر منتقل می شود

    از توابع دیگر برگشته است

به عبارت ساده تر، توابع درجه یک را می توان مانند هر متغیر یا شی دیگری در زبان مدیریت کرد. بیایید با چند مثال کدنویسی این قابلیت ها را تحلیل کنیم.

اختصاص توابع به متغیرها

به طور معمول، ما یک تابع را فراخوانی می کنیم و نتیجه آن را به یک متغیر اختصاص می دهیم. برای مثال:

در اینجا، add تابعی است که مجموع دو عدد را برمی گرداند. وقتی add(3, 4) فراخوانی می کنیم، 7 برمی گرداند که به result متغیر اختصاص داده می شود. خروجی این کد خواهد بود:

 <function add at 0x...> 7

حالا بیایید تابع add را به یک متغیر sum_function بدون فراخوانی (یعنی بدون پرانتز) اختصاص دهیم.

 sum_function = add

چاپ add و sum_function نشان می دهد که هر دو به یک شی تابع اشاره دارند:

 print(add) # Outputs: <function square at 0x...> print(sum_function) # Outputs: <function square at 0x...>

این نشان می دهد که توابع را می توان مانند هر نوع داده دیگری به متغیرها اختصاص داد. اکنون می‌توانیم از sum_function درست مانند تابع add اصلی استفاده کنیم و حتی نام تابع اصلی add را حذف کنیم، و تابع همچنان از طریق sum_function قابل دسترسی خواهد بود.

 del add print(sum_function(3, 4)) # Output: 7

عبور توابع به عنوان آرگومان

یکی دیگر از جنبه های توابع درجه یک، توانایی انتقال آنها به عنوان آرگومان به توابع دیگر است. این به انعطاف پذیری و ماژولار بودن بیشتر در کد اجازه می دهد.

بیایید این را با یک تابع map سفارشی نشان دهیم. یک تابع map یک تابع داده شده را برای هر آیتم در یک فهرست (یا آرایه) اعمال می کند و یک فهرست جدید با نتایج را برمی گرداند.

در این مثال، تابع double یک عدد n می گیرد و دو برابر آن را برمی گرداند. تابع map_function یک func تابع و فهرست ی از values را می گیرد، func برای هر عنصر در values اعمال می کند و یک فهرست جدید با نتایج برمی گرداند.

هنگامی که map_function با double و فهرست [3, 6, 9, 12, 15] فراخوانی می شود، تابع double را برای هر عنصر در فهرست اعمال می کند که نتیجه آن [6, 12, 18, 24, 30] است. این نشان می دهد که چگونه توابع را می توان به عنوان آرگومان برای ایجاد الگوهای کد انعطاف پذیر و قابل استفاده مجدد ارسال کرد.

توجه داشته باشید که هنگام ارسال تابع، پرانتز را وارد نمی‌کنیم (یعنی به جای double() double ، که نشان می‌دهد خود تابع را ارسال می‌کنیم و نتیجه فراخوانی تابع نیست.

برگرداندن توابع از سایر توابع

برگرداندن توابع از توابع دیگر یکی دیگر از ویژگی های مهم توابع درجه یک است. این مفهوم امکان ایجاد کدهای پیچیده تر و ماژولار را فراهم می کند که اغلب در سناریوهایی مانند ایجاد توابع قابل تنظیم یا بسته شدن استفاده می شود.

برای توضیح بیشتر، اجازه دهید به یک مثال عملی نگاه کنیم که در آن یک تابع تابع دیگری را برمی گرداند:

در این مثال، تابع create_multiplier یک factor پارامتر را می گیرد و multiplier تابع دیگری را برمی گرداند. این تابع multiplier وقتی با آرگومان x فراخوانی می شود، حاصلضرب x و factor را برمی گرداند.

وقتی create_multiplier با 2 فراخوانی می شود، تابعی را برمی گرداند که آرگومان خود را در 2 ضرب می کند. به طور مشابه، هنگامی که با 3 فراخوانی می شود، تابعی را برمی گرداند که آرگومان خود را در 3 ضرب می کند. این توابع بازگشتی ( double و triple ) را می توان با آرگومان هایی برای انجام ضرب فراخوانی کرد. برای مثال double(5) 10 و triple(5) 15 را برمی گرداند.

این ماهیت یک بسته شدن است – جایی که تابع برگشتی ( multiplier ) دسترسی به متغیر ( factor ) را از محدوده محصور خود حفظ می کند، حتی پس از اتمام اجرای تابع خارجی ( create_multiplier ). این به توابع ایجاد شده ( double و triple ) اجازه می دهد تا مقدار factor که با آن ایجاد شده اند را به خاطر بسپارند و از آن استفاده کنند.

توابع مرتبه بالاتر

تابع مرتبه بالاتر تابعی است که روی توابع دیگر عمل می کند. به طور خاص، یک تابع مرتبه بالاتر می تواند:

یک یا چند تابع را به عنوان آرگومان در نظر بگیرید

یک تابع را به عنوان نتیجه آن برگردانید

اساساً، توابع مرتبه بالاتر از توابع درجه یک استفاده می کنند تا آنها را به عنوان آرگومان در نظر بگیرند یا آنها را به عنوان نتیجه برگردانند و عملیات قدرتمندی را روی خود توابع ممکن می سازند. نمونه‌هایی از هر دو را قبلاً دیده‌ایم:

در مثال " عبور توابع به عنوان آرگومان " ما، map_function یک تابع مرتبه بالاتر است زیرا تابع ( double ) را به عنوان آرگومان می گیرد.

در مثال " بازگرداندن توابع از توابع دیگر "، create_multiplier یک تابع مرتبه بالاتر است زیرا تابع دیگری ( multiplier ) را در نتیجه برمی گرداند.

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

توابع لامبدا

توابع لامبدا در پایتون که با نام توابع ناشناس نیز شناخته می شوند، توابع کوچکی هستند که با استفاده از کلمه کلیدی lambda تعریف می شوند. آنها اغلب برای کارهای کوتاه مدت استفاده می شوند که نیازی به تعریف کامل تابع با def ندارند.

آنها اساسا قند نحوی برای تعریف توابع کوچک هستند. نحو یک تابع لامبدا به صورت زیر است:

 lambda arguments: expression

توابع لامبدا را می توان به عنوان آرگومان به توابع درجه بالاتر ارسال کرد یا از آنها بازگرداند و آنها را به ابزارهای همه کاره در برنامه نویسی تابعی تبدیل کرد.

مثال: استفاده از توابع لامبدا در یک تابع نقشه سفارشی

ما قبلاً مثال map_function را مورد بحث قرار دادیم. بیایید ببینیم چگونه می توانیم با استفاده از یک تابع لامبدا به همان عملکرد دست پیدا کنیم:

در این مثال، تابع لامبدا lambda n: n * 2 مستقیماً به map_function ارسال می شود و نیاز به تعریف تابع double جداگانه را از بین می برد.

مثال: ایجاد توابع ضرب کننده با Lambdas

با مشاهده مجدد مثال create_multiplier ، می توانیم از یک تابع لامبدا برای multiplier استفاده کنیم:

در اینجا، create_multiplier یک تابع لامبدا را برمی‌گرداند که ورودی آن را در factor مشخص شده ضرب می‌کند. این یک روش فشرده و گویا برای تعریف عملکرد یکسان است.

برای درک عمیق تر از توابع لامبدا، می توانید این آموزش را در اینجا تحلیل کنید.

وابستگی متقابل توابع مرتبه بالاتر و توابع درجه یک:

کارکردهای مرتبه بالاتر پیامد مستقیم شهروند درجه یک بودن عملکردها هستند. اگر بتوان با توابع مانند هر مقدار دیگری رفتار کرد، طبیعتاً نتیجه می شود که می توانید توابع را به توابع دیگر منتقل کنید و آنها را از توابع دیگر برگردانید.

پس می توانیم بگوییم - توابع مرتبه بالاتر ذاتاً بر مفهوم توابع درجه یک متکی هستند. بدون توابع درجه یک، نمی‌توانیم توابع درجه بالاتری داشته باشیم، زیرا توابع دوم به توانایی ارسال و برگرداندن توابع بستگی دارد.

بیایید با مثال های بیشتری بفهمیم:

مثال: تابعی با مرتبه بالاتر که تابعی را به عنوان آرگومان می گیرد (تابع درجه اول)

در این مثال، apply_operation یک تابع مرتبه بالاتر است زیرا تابع دیگری ( operation ) را به عنوان آرگومان می گیرد. توابع add و multiply توابع درجه یک هستند زیرا می توانند به عنوان آرگومان به توابع دیگر ارسال شوند.

تابع apply_operation سه پارامتر دارد: یک تابع ( operation ) و دو عدد صحیح ( x و y ). نتیجه اعمال تابع operation را به x و y برمی گرداند.

با فراخوانی apply_operation(add, 3, 4) 7 را برمی گرداند که حاصل جمع 3 و 4 است. به همین ترتیب، فراخوانی apply_operation(multiply, 3, 4) عدد 12 را برمی گرداند که حاصل ضرب 3 و 4 است. این انعطاف پذیری و انعطاف پذیری را نشان می دهد. قابلیت استفاده مجدد از توابع مرتبه بالاتر، نشان می دهد که چگونه می توانیم عملیات متفاوتی را در مجموعه ورودی های یکسان انجام دهیم.

مثال: یک تابع مرتبه بالاتر که تابع دیگری را برمی گرداند (تابع درجه اول)

در این مثال، discount_applier یک پارامتر discount_rate می گیرد و یک تابع جدید apply_discount برمی گرداند. این باعث می شود که آن یک "عملکرد مرتبه بالاتر" باشد و apply_discount به عنوان "عملکرد درجه یک" در نظر گرفته می شود زیرا در داخل discount_applier تعریف شده و برای استفاده بعدا برگردانده می شود.

این تابع apply_discount ، هنگامی که با آرگومان price فراخوانی می شود، قیمت تخفیف خورده محاسبه شده با استفاده از discount_rate را برمی گرداند.

هنگامی که discount_applier با نرخ تنزیل 20 فراخوانی می شود، تابعی را برمی گرداند که 20% تخفیف به آرگومان خود اعمال می کند. به طور مشابه، هنگامی که با نرخ تخفیف 15 فراخوانی می شود، تابعی را برمی گرداند که 15 درصد تخفیف اعمال می کند. این توابع برگشتی ( holiday_discount و member_discount ) می توانند برای اعمال تخفیف های مربوطه استفاده شوند.

با فراخوانی holiday_discount(100) ، 80.0 را برمی گرداند، با اعمال 20% تخفیف به 100. تماس با member_discount(100) 85.0 را برمی گرداند، با اعمال 15% تخفیف.

این مثال‌ها نشان می‌دهند که چگونه توابع درجه بالاتر با استفاده از قابلیت‌های توابع درجه یک، ایجاد الگوهای کد انعطاف‌پذیر، قابل استفاده مجدد و مدولار را امکان‌پذیر می‌سازند. آنها پایه و اساس بسیاری از تکنیک های برنامه نویسی پیشرفته از جمله بسته شدن را تشکیل می دهند و برای نوشتن کدهای رسا و قدرتمند ضروری هستند.

بسته شدن

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

به عبارت ساده تر، بسته شدن یک تابع درونی است که به متغیرهای تابع حاوی (یا بیرونی) خود دسترسی دارد، حتی پس از اتمام اجرای آن تابع خارجی.

بیایید به چند مثال نگاه کنیم تا بفهمیم بسته شدن در پایتون چگونه کار می کند:

تابع تودرتوی پایه با اجرای فوری

در این مثال، تابع outer_scope دو متغیر محلی را تعریف می‌کند: name و city . سپس تعریف می‌کند و بلافاصله inner_scope را فرا می‌خواند، که یک پیام تبریک با استفاده از متغیرهای name و city از محدوده محصور چاپ می‌کند.

هنگامی که outer_scope فراخوانی می شود، تابع تودرتو inner_scope اجرا می شود و پیام تبریک را تولید می کند: "سلام سام، درود از نیویورک".

بازگرداندن عملکرد درونی

حالا بیایید مثال را تغییر دهیم تا تابع داخلی بدون اجرای فوری آن را برگردانیم:

در اینجا outer_scope name و city به عنوان متغیرهایی مشابه مثال بالا تعریف می کند. سپس تابع inner_scope را تعریف و برمی گرداند اما این بار بدون فراخوانی آن (یعنی inner_scope به جای inner_scope() )

هنگامی که greeting_func = outer_scope() اجرا می شود، تابع inner_scope را که توسط outer_scope برگردانده شده است به greeting_func اختصاص می دهد.

اکنون، greeting_func اشاره ای به تابع inner_scope دارد. فراخوانی greeting_func() inner_scope را اجرا می‌کند که چاپ می‌کند: "سلام سام، درود از نیویورک".

حتی اگر زمانی که ما greeting_func() را فراخوانی می کنیم outer_scope به پایان رسیده است، تابع inner_scope (اکنون توسط greeting_func ارجاع داده شده است) دسترسی به name متغیرها و city را از محدوده خود حفظ می کند. این چیزی است که آن را به یک بسته تبدیل می کند - متغیرها را از محدوده حاوی خود "بسته است".

استفاده از بسته شدن با پارامترها

برای نشان دادن قدرت بسته شدن، بیایید با گفت ن پارامترهایی به تابع outer_scope یک مثال پویاتر ایجاد کنیم:

اکنون در اینجا، تابع outer_scope name و city را به عنوان پارامتر می گیرد. در داخل outer_scope ، تابع inner_scope برای چاپ پیام تبریک با استفاده از name و city تعریف شده است. به جای فراخوانی inner_scope ، outer_scope خود تابع inner_scope را برمی گرداند.

وقتی outer_scope با آرگومان‌های خاص فراخوانی می‌شود، بسته‌ای ایجاد می‌کند و برمی‌گرداند که این آرگومان‌ها را جمع‌آوری می‌کند. به عنوان مثال، greet_priyanshu بسته ای است که Dr Priyanshu و Jaipur را به یاد می آورد، در حالی که greet_sam Sam و New York را به یاد می آورد. هنگامی که این بسته ها فراخوانی می شوند، پیام های تبریک مربوطه را تولید می کنند.

حتی اگر outer_scope در هر دو مورد اجرا را به پایان رسانده است، توابع inner_scope (اکنون greet_priyanshu و greet_sam ) دسترسی به name و متغیرهای city مربوطه را از محدوده‌های محصور خود حفظ می‌کنند و رفتار بسته شدن را نشان می‌دهند.

اگر می خواهید، می توانید به جای تابع داخلی ما ( inner_scope ) از یک تابع لامبدا نیز استفاده کنید:

با استفاده از یک تابع لامبدا، به روشی مختصرتر به همان نتیجه می رسیم. بسته‌های ایجاد شده توسط outer_scope همچنان دسترسی به متغیرهای name و city را حفظ می‌کنند و همین رفتار بسته شدن را نشان می‌دهند.

کاربردهای دنیای واقعی بستن

اکنون اجازه دهید برخی از کاربردهای عملی بسته شدن در برنامه نویسی دنیای واقعی را ببینیم. در اینجا چند سناریو وجود دارد که معمولاً از بسته شدن استفاده می شود:

مدیریت رویداد در توسعه وب (نمونه js اما مورد استفاده مهم)

در جاوا اسکریپت، بستن اغلب برای مدیریت رویدادها، مانند کلیک روی دکمه، استفاده می شود.

توضیح :

createButtonHandler یک تابع مرتبه بالاتر است که یک buttonName به عنوان آرگومان می گیرد و یک تابع (بسته شدن) را برمی گرداند.

تابع بازگشتی (بستن) متغیر buttonName از محدوده واژگانی خود می گیرد.

هنگامی که یک دکمه کلیک می شود، بسته شدن مربوطه فراخوانی می شود و به buttonName که هنگام ایجاد کنترل کننده ارسال شده است دسترسی دارد.

حفظ وضعیت در برنامه های رابط کاربری گرافیکی

در پایتون، بسته‌ها را می‌توان برای حفظ حالت در برنامه‌های رابط کاربری گرافیکی (GUI) استفاده کرد، مانند مواردی که با Tkinter ایجاد شده‌اند.

توضیح :

create_counter یک تابع مرتبه بالاتر است که count به 0 مقداردهی اولیه می کند و یک تابع counter تودرتو تعریف می کند.

تابع counter یک بسته است که متغیر count از محدوده محصور می گیرد.

کلمه کلیدی nonlocal به بسته شدن اجازه می دهد تا متغیر count را تغییر دهد.

هر بار که روی دکمه کلیک می شود، تابع counter فراخوانی می شود و count افزایش داده و چاپ می کند.

برخی از برنامه های کاربردی دیگر عبارتند از:

ایجاد دکوراتورها

دکوراتورها در پایتون ابزاری قدرتمند برای اصلاح یا گسترش رفتار توابع و روش‌ها هستند. بسته شدن مکانیسم اساسی برای اجرای دکوراتورها است.

پنهان کردن و کپسوله کردن داده ها

می توان از بسته ها برای ایجاد متغیرها و متدهای خصوصی در یک تابع استفاده کرد که فقط توسط تابع داخلی قابل دسترسی و تغییر هستند. این روشی را برای دستیابی به کپسوله سازی در پایتون فراهم می کند.

نتیجه

توابع درجه یک به ما این امکان را می دهند که توابع را مانند هر شی یا نوع داده دیگری در نظر بگیریم و انعطاف پذیری را برای موارد زیر ارائه کنیم:

    آنها را به متغیرها اختصاص دهید

    آنها را به عنوان آرگومان به توابع دیگر منتقل کنید

    آنها را از توابع دیگر برگردانید

این قابلیت یک جنبه اساسی از بسیاری از تکنیک های برنامه نویسی پیشرفته از جمله بسته شدن است. درک توابع درجه یک اولین قدم در تسلط بر این مفاهیم پیچیده تر است.

از سوی دیگر، توابع مرتبه بالاتر این را یک گام فراتر می برند. آنها نه تنها به شما اجازه می دهند با توابع مانند داده رفتار کنید، بلکه به شما امکان می دهند از توابع برای ایجاد توابع جدید یا تغییر نحوه رفتار سایر توابع استفاده کنید. این راه را به روی راه های پیچیده تر و انعطاف پذیرتر برای حل مسائل در برنامه نویسی باز می کند.

آنها عملیاتی مانند:

    پذیرش توابع به عنوان آرگومان/پارامتر

    برگرداندن توابع به عنوان نتایج

در حالی که همه توابع درجه بالاتر شامل توابع درجه یک هستند، همه توابع درجه یک لزوماً توابع درجه بالاتر نیستند.

به طور خلاصه، بسته‌ها به توابع داخلی اجازه می‌دهند تا به متغیرها از محدوده خود دسترسی داشته باشند.

متغیرهای آزاد متغیرهایی هستند که در یک تابع درونی استفاده می شوند اما در یک تابع بیرونی تعریف می شوند.

استفاده عملی از بسته شدن شامل سناریوهایی است که در آن شما نیاز به توابع برای به خاطر سپردن وضعیت دارید، حتی پس از اتمام اجرای تابع خارجی.

خبرکاو

ارسال نظر




تبليغات ايهنا تبليغات ايهنا

تمامی حقوق مادی و معنوی این سایت متعلق به خبرکاو است و استفاده از مطالب با ذکر منبع بلامانع است