آموزش دستور return پایتون

امیرحسین بیگدلو 5 ماه قبل

دستور return پایتون یکی از مهمترین اجزای فانکشن‌‌ها و متدها است. میتوانید از return برای برگرداندن یک آبجکت به فراخوان کننده متد یا فانکشن استفاده کنید. این آبجکت ها به عنوان return value شناخته میشوند. استفاده درست از دستور return باعث میشود کد تمیزتر و پایتونی تری بنویسید.

 

ویدیو پیشنهادی: ویدیو آشنایی عمیق با function در پایتون

 

 #  فانکشن‌های پایتون

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

یکسری دستور که یک مقدار را return میکنند. همچنین میتوانند صفر یا بیشتر آرگومان گرفته و در بدنه خود استفاده کنند.

 

به طور کلی فانکشن آرگومان را گرفته(اگر وجود داشته باشد)، یکسری کارها را روی آن انجام داده و مقداری را برگشت میدهد. به مقداری که فانکشن برگشت میدهد، مقدار برگشتی یا return value گفته میشود. تمام فانکشن‌های پایتون یک مقدار برگشتی دارند، چه ضمنی و چه صریح. در ادامه با هر دو این مقادیر آشنا خواهید شد.

 

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

def function_name(arg1, arg2,..., argN):
    # Function's code goes here...
    pass

 

برای استفاده از فانکشن باید آنرا صدا بزنید. برای اینکار نام فانشکن را همراه با آرگومان‌ها مینویسید:

function_name(arg1, arg2, ..., argN)

 

شما باید آرگومان‌ها را فقط در صورتی که فانشکن‌ به آنها نیاز داشته باشد، ارسال کنید.

 

دوره پیشنهادی: دوره آموزش پایتون (python)

 

 #  درک دستور return پایتون

دستور return یک دستور خاص است که در بدنه یک فانکشن یا متد برای برگرداندن یک آبجکت به فراخوان کننده استفاده میشود. مقدار بازگشتی میتواند هر آبجکتی از پایتون باشد. هر چیزی در پایتون آبجکت است. پس شما میتوانید هر چیزی را return کنید اعداد(int, float)،‌ دنباله‌ها(list, tuple, set, dictionary)، فانکشن‌ها، کلاس‌ها،‌ ماژول‌ها و پکیج‌ها.

 

حتی میتوانید دستور return را به تنهایی بدون مقدار استفاده کنید یا میتوانید کلا دستور return را از یک فانکشن حذف کنید که در هر دو صورت به صورت پیشفرض مقدار None بازگشت داده خواهد شد.

 

ویدیو پیشنهادی: ویدیو آموزش انواع return None در پایتون

 

 +  دستور return صریح

یک دستور return صریح بلافاصله فانکشن را متوقف کرده و مقدار بازگشتی را return میکند. برای اینکار باید از کلمه کلیدی return در فانکشن خود استفاده کنید:

>>> def return_42():
...     return 42  # An explicit return statement
...

>>> return_42()  # The caller code gets 42
42

 

زمانی که فانکشن return_42 را ساختید، دستور return را مستقیما در بدنه فانکشن استفاده کردید. این به این معنی است که هربار که فانکشن return_42 را اجرا کنید، عدد 42 را برای شما برمیگرداند.

 

اگر از return صریح استفاده کنید، میتوانید مقدار بازگشتی را به هر شکلی استفاده کنید:

>>> num = return_42()
>>> num
42

>>> return_42() * 2
84

>>> return_42() + 5
47

 

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

 

دقت کنید که شما فقط میتوانید از دستور return داخل یک فانکشن یا متد استفاده کنید، اگر هرجای دیگری از return استفاده کنید به ارور خواهید خورد:

>>> return 42
  File "<stdin>", line 1
SyntaxError: 'return' outside function

 

شما میتوانید هر آبجکتی را با دستور return برگردانید. از آنجایی که همه چیز در پایتون یک آبجکت است پس عملا میتوانید هر چیزی را برگردانید. مثلا فرض کنید میخواهید یک فانکشن بنویسید که یک لیست از اعداد را گرفته و لیستی از اعداد زوج را به شما برمیگرداند:

>>> def get_even(numbers):
...     even_nums = [num for num in numbers if not num % 2]
...     return even_nums
...

>>> get_even([1, 2, 3, 4, 5, 6])
[2, 4, 6]

 

فانکشن get_even از یک list comprehension استفاده میکند تا بتواند اعداد زوج را استخراج کند. و در آخر یک لیست را به عنوان مقدار بازگشتی return میکنیم.

 

حتی میتوانید مستقیما عبارت list comprehension را در مقابل دستور return قرار دهید:

>>> def get_even(numbers):
...     return [num for num in numbers if not num % 2]
...

>>> get_even([1, 2, 3, 4, 5, 6])
[2, 4, 6]

 

در این حالت list comprehension اجرا شده و سپس مقدار آن توسط دستور return برگشت داده میشود. دقت کنید که فقط عبارات اجرایی را میتوانید مستقیما در مقابل return قرار دهید و مواردی مثل حلقه(for, while) یا شرط(if) متفاوت است.

 

مقاله پیشنهادی: ماژول‌ها و پکیج‌های پایتون

 

 +  دستور return ضمنی

فانکشن‌های پایتون همیشه دستور return را دارند. اگر در مقابل دستور return چیزی ننویسید یا کلا از دستور return استفاده نکنید، پایتون به طور اتوماتیک مقدار پیشفرضی را برای شما return میکند. مقدار پیشفرض همیشه None است.

 

فرض کنید یک فانکشن نوشته اید که عددی را گرفته و به آن یکی اضافه میکند. در این فانکشن فراموش کرده‌اید که از دستور return استفاده کنید. در این حالت پایتون از return ضمنی استفاده خواهد کرد و مقدار None را برگشت میدهد:

>>> def add_one(x):
...     # No return statement at all
...     result = x + 1
...

>>> value = add_one(5)
>>> value

>>> print(value)
None

 

اگر شما به طور مستقیم از دستور return استفاده نکنید پایتون به طور اتوماتیک و ضمنی اینکار را برای شما کرده و مقدار None را return میکند. در کد بالا فانکشن add_one عدد را گرفته و یکی به آن اضافه میکند اما نتیجه return نمیکند. به خاطر همین است که مقدار value برابر None است. برای حل این مشکل باید return result را استفاده کنید.

 

مثال دیگر از فانشکنی که مقدار بازگشتی ندارد print است. وظیفه این دستور چاپ یک مقدار است و این فانکشن نیازی به دستور return ندارد:

>>> return_value = print("Hello, World")
Hello, World

>>> print(return_value)
None

 

مهم نیست که فانکشن‌ شما چقدر مهم یا پیچیده است، اگر برای آن چیزی return نکنید، پایتون به طور اتوماتیک None را return میکند.

 

مقاله پیشنهادی: آموزش دستور import در پایتون

 

 #  return در مقابل print

اگر در حالت تعاملی(interactive) پایتون کار کنید ممکن است فکر کنید که print کردن و return کردن هر دو یکسان هستند. اما اینطور نیست. دو فانکشن زیر را که در حالت تعاملی ساخته شده‌اند را ببینید:

>>> def print_greeting():
...     print("Hello, World")
...

>>> print_greeting()
Hello, World

>>> def return_greeting():
...     return "Hello, World"
...

>>> return_greeting()
'Hello, World'

 

هر دوی فانکشن‌ها در ظاهر یک کار انجام میدهند. در هر دو حالت جمله Hello World در صفحه نمایش داده میشود. اما یک تفاوت کوچک هست - وجود کوتیشن در مثال دوم. حالا ببینید که اگر از نوع داده دیگری استفاده کنیم، چه اتفاقی میفتد:

>>> def print_42():
...     print(42)
...

>>> print_42()
42

>>> def return_42():
...     return 42
...

>>> return_42()
42

 

در این حالت بین دو فانکشن هیج تفاوتی وجود ندارد. این نتیجه ممکن است برای تازه‌کارها گیج کننده باشد. در ظاهر هیچ تفاوتی وجود ندارد.

 

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

def add(a, b):
    result = a + b
    return result

add(2, 2)

 

فانکشن add دو عدد گرفته،‌ آنها را جمع کرده و نتیجه را return میکند. در خط 5 ما اعدد 2 را به فانشکن add ارسال کردیم. از آنجایی که شما الآن در حال یادگیری تقاوت print و return هستید فکر کنید که قرار است عدد 4 برای شما نشان داده شود. کد خود را با نام adding.py ذخیره کرده و آنرا اجرا کنید:

$ python3 adding.py

 

اگر شما فایل adding.py را در کامند لاین اجرا میبیند که هیچ نتیجه‌ای نخواهید دید. این بخاطر اینست که زمانی که کدتان را به شکل اسکریپت اجرا میکنید مقدار return شده برخلاف حالت تعاملی چاپ نخواهد شد.

 

اگر بخواهید پایتون نتیجه را برای شما چاپ کند باید به طور صریح از دستور print استفاده کنید:

def add(a, b):
    result = a + b
    return result

print(add(2, 2))

 

حالا اگر کدتان را با python adding.py اجرا کنید عدد 4 برای شما چاپ میشود.

 

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

 

ویدیو پیشنهادی: ویدیو آموزش ماژول argparse پایتون

 

 #  return کردن چند مقدار

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

 

برای مثال، فرض کنید باید فانکشنی بنویسید که نمونه ای از داده های عددی را گرفته و خلاصه ای از معیارهای آماری را برمی گرداند. برای کدنویسی این فانکشن، می توانید از ماژول statistics استاندارد پایتون استفاده کنید.

 

در اینجا مثالی از این فانکشن آمده است:

import statistics as st

def describe(sample):
    return st.mean(sample), st.median(sample), st.mode(sample)

 

در فانکشن describe از توانایی پایتون برای return کردن چند مقدار استفاده کرده‌اید. بعد از ساختن این فانکشن، میتوانید از دیگر توانایی پایتون به نام iterable unpacking استفاده کنید که میتواند مقادیر return شده را در متغیرهای جداگانه پخش کنید:

>>> sample = [10, 2, 4, 7, 9, 3, 9, 8, 6, 7]
>>> mean, median, mode = describe(sample)

>>> mean
6.5

>>> median
7.0

>>> mode
7

>>> desc = describe(sample)
>>> desc
(6.5, 7.0, 7)

>>> type(desc)
<class 'tuple'>

 

در این سه مقدار return شده در فانکشن describe را بین سه متغیر mean, median و mode تقیسم کردید. و سپس در بخش آخر،‌ سه متغیر را در یک متغیر desc ذخیره کردید که در نتیجه به یک tuple تبدیل شد.

 

فانکشن داخلی divmod هم چند مقدار را return میکند. این فانکشن دو عدد گرفته و ضریب دو عدد و باقیمانده را برای شما برمیگرداند:

>>> divmod(15, 3)
(5, 0)

>>> divmod(8, 3)
(2, 2)

 

این یک مثال از فانکشنی است که چند مقدار را return میکند.

 

دوره پیشنهادی: دوره آموزش GraphQL در پایتون

 

 #  بهترین روش استفاده از return پایتون

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

 

در این بخش شما چند روش خوب برای استفاده از دستور return را خواهید دید. این روش‌ها به شما کمک میکنند کدهای تمیزتر و خواناتری را بنویسید.

 

 

 +  استفاده صریح از return

خیلی از برنامه نویسان به returnهای ضمنی که پایتون به طور اتوماتیک انجام میدهد، تکیه میکنند. این ممکن است برای برنامه نویسانی که از زبان‌های دیگر آمده‌اند گیج کننده باشد.

 

سناریوهایی وجود دارد که در آن میتوانید از return None صریح استفاده کنید. در بقیه موارد میتوانید بر return اتوماتیک پایتون تکیه کنید:

  • اگر فانکشن شما کار خاصی را انجام میدهد اما مقدار مفیدی برای return ندارد، میتوانید از return None استفاده کنید.
  • اگر فانکشن شما returnهای متعددی دارد و return None هم یکی از آن گزینه‌ها است،‌ بهتر است به طور صریح از return None استفاده کنید.

 

این روش‌ها می توانند خوانایی و قابلیت نگهداری کد شما را با بیان صریح منظور شما بهبود ببخشند.

 

وقتی میخواهید از return None استفاده کنید،‌ به سه روش میتوانید اینکار را انجام دهید:

  • حذف کامل دستور return و تکیه بر رفتار پیشفرض پایتون
  • استفاده تنها از دستور return بدون مشخص کردن مقدار بازگشتی
  • استفاده صریح از return None

 

در اینجا یک مثال کامل هست:

>>> def omit_return_stmt():
...     # Omit the return statement
...     pass
...
>>> print(omit_return_stmt())
None

>>> def bare_return():
...     # Use a bare return
...     return
...
>>> print(bare_return())
None

>>> def return_none_explicitly():
...     # Return None explicitly
...     return None
...
>>> print(return_none_explicitly())
None

 

استفاده هر کدام از این روش‌ها کاملا تصمیمی شخصی است. اما باید در نظر داشته باشید که استفاده کامل از return None میتواند مشکلات نگهدار را کاهش دهد مخصوصا برای برنامه نویسانی که از زبان‌های دیگر آمده‌اند.

 

مقاله پیشنهادی: اعتبارسنجی آدرس ایمیل با regex با پایتون

 

 +  به یاد داشتن مقدار بازگشتی

در زمان نوشتن کد، ممکن است استفاده از return را فراموش کنید. در این حالت پایتون برای شما None را برمیگرداند. این حالت ممکن است باعث مشکلات کوچکی شود.

 

برای حل این مشکل میتوانید بلافاصله بعد از هدر فانکشن return خود را بنویسید. بعد میتوانید بدنه فانکشن را بنویسید:

def template_func(args):
    result = 0  # Initialize the return value
    # Your code goes here...
    return result  # Explicitly return the result

 

اگر به این روش عادت کنید، دیگر به دستور return را از دست نخواهید داد. این روش باعث افزایش کارایی شما در زمان debugging خواهد شد.

 

 

 +  خودداری از عبارت return پیچیده

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

 

مثال زیر را در نظر بگیرید:

>>> def variance(data, ddof=0):
...     mean = sum(data) / len(data)
...     return sum((x - mean) ** 2 for x in data) / (len(data) - ddof)
...

>>> variance([3, 4, 7, 5, 6, 2, 9, 4, 1, 3])
5.24

 

محاسبه‌ای که در این کد وجود دارد برای فهمیدن بسیار پیچیده است. همچنین در زمان اشکال زدایی نیز کارتان سخت است. برای حل این مشکل میتوانید محاسبات را پخش کنید. کد زیر ساده شده‌ کد بالا است:

>>> def variance(data, ddof=0):
...     n = len(data)
...     mean = sum(data) / n
...     total_square_dev = sum((x - mean) ** 2 for x in data)
...     return total_square_dev / (n - ddof)
...

>>> variance([3, 4, 7, 5, 6, 2, 9, 4, 1, 3])
5.24

 

در مثال بالا با استفاده از یکسری متغیر موقت، کدمان را ساده‌تر کرده‌ایم. متغیرهای موقت مانند n, mean یا total_square_dev کار شما را برای اشکال زدایی راحت میکنند. اگر یکی از آنها به مشکل خورد، میتوانید با دستور print مقدار آنرا جداگانه ببینید.

 

به طور کلی باید از عبارات return پیچیده خودداری کنید. به جای آن میتوانید کدتان را با متغیر‌های موقت به قطعات کوچکتری بشکنید.

 

دوره پیشنهادی: دوره اول آموزش جنگو(django)

 

 +  استفاده از return به همراه دستورات شرطی

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

 

فرض کنید قرار است فانکشنی بنویسید که عددی را گرفته و مقدار مثبت آن را برگرداند. اگر عدد بزرگتر از صفر باشد، خود عدد را برمیگرداند. اگر عدد منفی باشد، مقدار مثبت آنرا برمیگرداند:

>>> def my_abs(number):
...     if number > 0:
...         return number
...     elif number < 0:
...         return -number
...

>>> my_abs(-15)
15

>>> my_abs(15)
15

 

فانکشن my_abs دارای دو return است که در شرایط مختلف عمل میکنند. اگر عدد بزرگتر از صفر باشد return که در بلاک if هست اجرا خواهد شد و اگر عدد کوچکتر از صفر باشد، return که در بلاگ elif هست اجرا خواهد شد. اما اگر عدد صفر باشد در اینصورت مقدار None برگشت داده خواهد شد چون هیچ دستور return برای این حالت نوشته نشده است:

>>> print(my_abs(0))
None

 

برای حال این مشکل میتوانید return سوم را نیز اضافه کنید:

>>> def my_abs(number):
...     if number > 0:
...         return number
...     elif number < 0:
...         return -number
...     else:
...         return 0
...

>>> my_abs(0)
0

>>> my_abs(-15)
15

>>> my_abs(15)
15

 

حالا my_abs تمام حالت‌ها را بررسی میکند. هدف از این مثال این بود که ببینید میتوانید چند دستور return را در یک فانکشن استفاده کنید.

 

در آخر میتوانید فانکشن my_abs را ساده‌تر کنید:

>>> def my_abs(number):
...     if number < 0:
...         return -number
...     return number
...

>>> my_abs(0)
0

>>> my_abs(-15)
15

>>> my_abs(15)
15

 

به یاد داشته باشید تمام شرایط ممکن را تست کرده و برای تمام آنها مقدار return مناسب قرار دهید در غیر اینصورت برنامه شما یک باگ مخفی دارد.

 

دوره پیشنهادی: دوره آموزش تست نویسی در پایتون

 

 +  استفاده از return به همراه True و False

یک دیگر از حالت‌های استفاده از return، استفاده در کنار است. در این نوع فانکشن‌های یکی از موارد True یا False بازگردانده خواهد شد.

 

فرض کنید قرار است فانکشنی بنویسید که دو عدد a, b گرفته و بررسی کند که آیا عدد a بر b بخش پذیر است یا خیر. اگر بخش پذیر باشد مقدار True و اگر نباشد مقدار False برگشت داده خواهد شد:

>>> def is_divisible(a, b):
...     if not a % b:
...         return True
...     return False
...

>>> is_divisible(4, 2)
True

>>> is_divisible(7, 4)
False

 

 

 +  استفاده از return به همراه حلقه‌هایی با اتصال کوتاه

دستورات return که داخل حلقه استفاده میشوند به نوعی یک حقله short-circuit ایجاد میکند. این باعث میشود حلقه بلافاصله از چرخش خارج شود. برای درک بهتر این یک فانکشن مینویسیم که متد any پایتون را شبیه سازی میکند:

>>> def my_any(iterable):
...     for item in iterable:
...         if item:
...             # Short-circuit
...             return True
...     return False

>>> my_any([0, 0, 1, 0, 0])
True

>>> my_any([0, 0, 0, 0, 0])
False

 

اگر item در iterable درست باشد، وارد شرط if شده و سپس دستور return اجرا میشود. در این حالت دستور return باعث خروج از حلقه for میشود. اگر هیچکدام از itemها درست نباشند، فانکشن در آخر False را return میکند.

 

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

 

باید دقت کنید که در زمان استفاده از return داخل حلقه for، آنرا در یک شرط if قرار دهید. در غیر اینصورت حلقه در اولین چرخش متوقف خواهد شد.

 

ویدیو پیشنهادی: ویدیو آموزش حلقه for پایتون

 

 +  شناسایی کد مرده(dead code)

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

 

کد زیر را در نظر بگیرید که بعد از return دستور print را دارد:

>>> def dead_code():
...     return 42
...     # Dead code
...     print("Hello, World")
...

>>> dead_code()
42

 

از آنجایی که دستور print بعد از return است، هیچ وقت اجرا نخواهد شد. شناسایی کدهای مرده و حذف آنها به خوانایی کد شما کمک میکند. دقت کنید که اگر در کدتان شرط if باشد دیگر کد مرده نخواهید داشت:

>>> def no_dead_code(condition):
...     if condition:
...         return 42
...     print("Hello, World")
...

>>> no_dead_code(True)
42
>>> no_dead_code(False)
Hello, World

 

در کد بالا دستور print دیگر کد مرده نیست، چون خارج از شرط if قرار گرفته و اگر condition برابر False باشد، اجرا خواهد شد.

 

ویدیو پیشنهادی: ویدیو آموزش لامبدا(lambda) در پایتون

 

 #  return کردن فانکشن‌های پایتون

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

 

فانکشنی که یک فانکشن‌ دیگر را به عنوان آرگومان قبول میکند یا یک فانکشن را به عنوان نتیجه return میکند را higher-order میگویند. به فانکشن‌هایی که در داخل یک فانکشن دیگر قرار دارند نیز، closure گفته میشود. فانکشن‌های داخلی اطلاعات میتوانند حالت قبلی اجرا شده را در خود نگهدارند:

>>> def by_factor(factor):
...     def multiply(number):
...         return factor * number
...     return multiply
...

>>> double = by_factor(2)
>>> double(3)
6
>>> double(4)
8

>>> triple = by_factor(3)
>>> triple(3)
9
>>> triple(4)
12

 

در داخل by_factor فانکشنی به نام multiply ساخته و بدون صدا زدن، آنرا return میکنیم. در این حالت multiply وضعیت فانکشن را بین فراخوانی‌ها حفظ میکند.

 

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

>>> def by_factor(factor):
...     return lambda number: factor * number
...

>>> double = by_factor(2)
>>> double(3)
6
>>> double(4)
8

 

این کد هم درست همانند کد قبل، به درستی کار خواهد کرد.

 

ویدیو پیشنهادی: ویدیو آموزش حرفه‌ای دکوراتورها در پایتون

 

 #  return کردن در دکوراتور پایتون

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

 

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

 

در کد زیر یک دکوراتور ساخته‌ایم که زمان اجرای فانکشن را اندازه گیری میکند:

>>> import time

>>> def my_timer(func):
...     def _timer(*args, **kwargs):
...         start = time.time()
...         result = func(*args, **kwargs)
...         end = time.time()
...         print(f"Execution time: {end - start}")
...         return result
...     return _timer
...

>>> @my_timer
... def delayed_mean(sample):
...     time.sleep(1)
...     return sum(sample) / len(sample)
...

>>> delayed_mean([10, 2, 4, 7, 9, 3, 9, 8, 6, 7])
Execution time: 1.0011096000671387
6.5

 

در کد بالا یک دکوراتور به نام my_timer ساختیم که روی delayed_mean کار میکند. پایتون به محض اینکه یک ماژول یا اسکریپت را import کنید،‌ اجرا میکند. پس زمانی که delaye_mean را فراخوانی میکنید، در واقع درحال فراخوانی مقدار بازگشتی my_timer هستند که آبجکت time_ است.

 

همانطور که در کد بالا دیدید، میتوانید فانکشن‌ها را در یک دکوراتور نیز return کنید.

 

ویدیو پیشنهادی: ویدیو توضیح مدیریت خطاها در پایتون

 

 #  استفاده از return در بلاک try-except پایتون

اگر یک دستور return را در بلاک try و finally استفاده کنید، کدی که در داخل finally قرار داده‌اید، همیشه قبل از دستور return اجرا خواهد شد. این کار باعث میشود که مطمئن شویم کدی که در finally هست، همیشه اجرا میشود. این مثال را ببینید:

>>> def func(value):
...     try:
...         return float(value)
...     except ValueError:
...         return str(value)
...     finally:
...         print("Run this before returning")
...

>>> func(9)
Run this before returning
9.0

>>> func("one")
Run this before returning
'one'

 

زمانی که func را صدا میزنید، قبل از اینکه دستور return اتفاق بیفتد، بخش finally اجرا میشود.

 

ویدیو پیشنهادی: ویدیو آموزش generator در پایتون

 

 #  استفاده از return در generator پایتون

یک فانکشن پایتون با yield در بدنه آن، یک generator است. وقتی یک generator را صدا میزنید، یک generator iterator برای شما return میشود. شما میتوانید از return داخل generator استفاده کنید که یعنی کار generator شما به پایان رسیده. دستور return باعث میشود که پایتون یک StopIteration ایجاد کند.

 

در اینجا یک generator هست که دو مقدار را yield و در آخر مقدار سوم را return میکند:

>>> def gen():
...     yield 1
...     yield 2
...     return 3
...

>>> g = gen()
>>> g
<generator object gen at 0x7f4ff4853c10>

>>> next(g)
1
>>> next(g)
2

>>> next(g)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    next(g)
StopIteration: 3

 

برای گرفتن هر مقدار از generator باید از next استفاده کنید که یک متد داخلی پایتون است که آیتم بعدی در generator را میگیرد. در دو فراخوانی اول مقادیر 1 و 2 برگشت داده میشود اما دفعه سوم یک StopIteration ایجاد خواهد شد.

 

 

 #  نتیجه گیری

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

مطالب مشابه



مونگارد