وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

توابع تو در تو پایتون

0 44
زمان لازم برای مطالعه: 5 دقیقه


توابع تودرتو چیست؟

توابع یکی از “شهروندان درجه یک” پایتون هستند، به این معنی که توابع با سایر اشیاء پایتون مانند اعداد صحیح، رشته‌ها، ماژول‌ها و غیره هم سطح هستند. به عنوان ارزش ها و غیره

پایتون از مفهوم “عملکرد تودرتو” یا “عملکرد داخلی” پشتیبانی می کند، که به سادگی تابعی است که در داخل تابع دیگری تعریف شده است. در ادامه مقاله از دو کلمه “عملکرد درونی” و “عملکرد تودرتو” به جای یکدیگر استفاده خواهیم کرد.

دلایل مختلفی وجود دارد که چرا یک فرد مایل به ایجاد یک تابع در یک تابع دیگر است. تابع داخلی قادر به دسترسی به متغیرهای داخل محدوده محصور است. در این مقاله، جنبه های مختلف توابع داخلی در پایتون را بررسی خواهیم کرد.

تعریف یک عملکرد درونی

برای تعریف یک تابع درونی در پایتون، به سادگی با استفاده از پایتون یک تابع در داخل تابع دیگری ایجاد می کنیم def کلمه کلیدی. به عنوان مثال:

def function1(): 
    print ("Hello from outer function")
    def function2(): 
        print ("Hello from inner function")
    function2()

function1()

خروجی

Hello from outer function
Hello from inner function

در مثال بالا، function2() در داخل تعریف شده است function1()، آن را به یک عملکرد درونی تبدیل می کند. تماس گرفتن function2()، ابتدا باید تماس بگیریم function1(). این function1() سپس ادامه خواهد داد و تماس خواهد گرفت function2() همانطور که در داخل آن تعریف شده است.

ذکر این نکته ضروری است که برای اجرای تابع داخلی باید تابع خارجی فراخوانی شود. اگر تابع خارجی فراخوانی نشود، تابع داخلی هرگز اجرا نخواهد شد. برای نشان دادن این موضوع کد بالا را به شکل زیر تغییر داده و اجرا کنید:

def function1(): 
    print ("Hello from outer function")
    def function2(): 
        print ("Hello from inner function")
    function2()

کد هنگام اجرا چیزی برنمی‌گرداند!

در اینجا یک مثال دیگر وجود دارد:

def num1(x):
   def num2(y):
      return x * y
   return num2
res = num1(10)

print(res(5))

خروجی

50

کد ضرب دو عدد، یعنی 10 و 5 را برمی گرداند. مثال نشان می دهد که یک تابع داخلی قادر به دسترسی به متغیرهای قابل دسترسی در تابع خارجی است.

تا اینجا دیدید که امکان دسترسی به متغیرهای تابع خارجی در داخل تابع داخلی برای ما وجود دارد. اگر بخواهیم متغیرهای تابع بیرونی را از داخل تابع داخلی تغییر دهیم، چه؟ بیایید ببینیم چه اتفاقی می افتد:

def function1(): 
    x = 2 
    def function2(a): 
       
       
        x = 6
        print (a+x)
    print (x) 
    function2(3)

function1()

خروجی

2
9

خروجی نشان می دهد که این امکان برای ما وجود دارد که مقدار یک متغیر تعریف شده در تابع خارجی را از تابع داخلی نمایش دهیم، اما آن را تغییر ندهیم. صورتحساب x = 6 به ما کمک کرد تا یک متغیر جدید ایجاد کنیم x داخل عملکرد داخلی function2() به جای تغییر مقدار متغیر x در تابع بیرونی تعریف شده است function1().

در بخش بعدی، دلایل اصلی استفاده از توابع داخلی در پایتون را مورد بحث قرار خواهیم داد.

پیشنهاد می‌کنیم بخوانید:  روش به هم پیوستن رشته ها در پایتون

چرا از توابع درونی استفاده کنیم؟

کپسوله سازی

یک تابع را می توان به عنوان یک تابع درونی ایجاد کرد تا از آن در برابر هر چیزی که خارج از تابع اتفاق می افتد محافظت کند. در آن صورت، تابع از محدوده جهانی پنهان می شود. به عنوان مثال:

def outer_function(x):
    
    def inner_increment(x):
        return x + 2
    y = inner_increment(x)
    print(x, y)

inner_increment(5)

خروجی

Traceback (most recent call last):
  File "C:/Users/admin/inner.py", line 7, in <module>
    inner_increment(5)
NameError: name 'inner_increment' is not defined

در کد بالا، ما در تلاش هستیم تا با inner_increment() تابع، اما در عوض یک خطا دریافت کردیم.

اکنون، تماس را به کامنت بگذارید inner_increment() و تماس را لغو نظر کنید outer_function() همانطور که در زیر نشان داده شده است:

def outer_function(x):
    
    def inner_increment(x):
        return x + 2
    y = inner_increment(x)
    print(x, y)


outer_function(5)

خروجی

5 7

اسکریپت بالا نشان می دهد که عملکرد درونی، یعنی inner_increment() از آن چه در خارج از آن اتفاق می افتد از متغیر محافظت می شود x درون inner_increment تابع تحت تأثیر مقدار ارسال شده به پارامتر قرار نمی گیرد x از عملکرد بیرونی به عبارت دیگر متغیرهای داخل تابع درونی خارج از آن قابل دسترسی نیستند. یک مزیت بزرگ با چنین الگوی طراحی وجود دارد. پس از بررسی همه آرگومان ها در تابع خارجی، می توانیم با خیال راحت از بررسی خطا در تابع داخلی صرف نظر کنیم.

بسته شدن و عملکرد کارخانه

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

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

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

پیشنهاد می‌کنیم بخوانید:  درون یابی رشته پایتون با عملگر درصد (%)

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

شرایط زیر برای ایجاد بسته شدن در پایتون الزامی است:

  • باید یک تابع تو در تو وجود داشته باشد
  • تابع داخلی باید به مقداری اشاره کند که در محدوده محصور تعریف شده است
  • تابع enclosing باید تابع تودرتو را برگرداند

به مثال زیر توجه کنید:

def function1(name):
    def function2():
        print('Hello ' + name)
    return function2

func = function1('Nicholas')
func()

خروجی

Hello Nicholas

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

توابع درونی به ما در تعریف کمک می کنند توابع کارخانه. تابع کارخانه تابعی است که شی دیگری را ایجاد می کند. مثلا:

def power_generator(num):

    
    def power_n(power):
        return num ** power

    return power_n

power_two = power_generator(2)
power_three = power_generator(3)
print(power_two(8))
print(power_three(4))

خروجی

256
81

در اسکریپت بالا، از power_n(power) تابع، ما دو شی دیگر ایجاد کرده ایم، power_two و power_three. این باعث می شود power_n(power) یک عملکرد کارخانه از آنجایی که آن را تولید می کند power_two و power_three توابع برای ما با استفاده از پارامتری که به آن پاس می دهیم.

نتیجه

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

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-25 15:12:07

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید