توابع

تفاوت return و print در پایتون؛ None و برگرداندن چند مقدار

۳ دقیقه مطالعه · به‌روزرسانی ۲۲ مهر ۱۴۰۵

یکی از پرتکرارترین سردرگمی‌های تازه‌کارها این است: «تابع من عدد را نشان می‌دهد، پس چرا نمی‌توانم از نتیجه‌اش استفاده کنم؟» جواب در فرق print و return است.

مقایسه

return print
فقط داخل تابع معنی دارد هر جایی قابل استفاده است
فقط یک return در هر اجرای تابع اجرا می‌شود می‌شود چندین print اجرا کرد
بعد از اجرای آن، تابع تمام می‌شود؛ کدهای بعدی اجرا نمی‌شوند بعد از آن، کدهای بعدی هم اجرا می‌شوند
مقداری را به صداکنندهٔ تابع تحویل می‌دهد هیچ مقداری برنمی‌گرداند؛ فقط روی صفحه نشان می‌دهد

print مثل این است که جواب را بلند بگویید: همه می‌شنوند ولی کسی آن را یادداشت نمی‌کند. return مثل این است که جواب را روی کاغذ بنویسید و دست صداکننده بدهید: می‌تواند نگهش دارد، در متغیر بریزد و با آن حساب کند.

سه نسخه از یک تابع

فقط return

def sum_3num(a, b, c):
    return a + b + c

x = sum_3num(1, 2, 3)
print(x * 10)    # 60؛ می‌توانیم با نتیجه کار کنیم

فقط print

def sum_3num(a, b, c):
    print(a + b + c)

x = sum_3num(1, 2, 3)   # 6 چاپ می‌شود
print(x)                # None !
print(x * 10)           # TypeError

اجرا کنید: عدد ۶ روی صفحه می‌آید، ولی x مقدار None دارد و ضرب آن در ۱۰ خطا می‌دهد.

هم print، هم return

def sum_3num(a, b, c):
    d = a + b + c
    print(d)
    return d

x = sum_3num(1, 2, 3)
print(x * 10)

تابع بدون return، None برمی‌گرداند

اگر تابعی هیچ دستور returnی نداشته باشد (یا اجرا به آن نرسد)، پایتون خودکار None برمی‌گرداند. None یعنی «هیچ مقداری». ببینید:

def is_even(i):
    """
    Input: i, a positive int
    Does not return anything
    """
    i % 2 == 0      # محاسبه می‌شود ولی return نشده!

print(is_even(4))

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

بعد از return، هیچ چیز اجرا نمی‌شود

def test():
    print("hi")
    print("bye")
    return 12
    print("salam")   # هرگز اجرا نمی‌شود
    print("ahay")    # هرگز اجرا نمی‌شود

a = test()
print(a)

خروجی hi، bye و 12 است. به محض رسیدن به return، تابع تمام می‌شود.

از این ویژگی برای خروج زودهنگام استفاده می‌کنیم. مثلاً در is_prime به محض پیدا شدن یک مقسوم‌علیه return False می‌کنیم؛ هم کد کوتاه‌تر می‌شود و هم دیگر نیازی به break و پرچم نیست.

💡 در Jupyter گول نخورید: اگر آخرین خط یک سلول test() باشد، Jupyter مقدار برگشتی را هم زیر سلول نمایش می‌دهد (Out[3]: 12). این را با print اشتباه نگیرید؛ در یک فایل ‎.py‎ آن 12 نمایش داده نمی‌شود.

برگرداندن چند مقدار

در ریاضی، تابع برای هر ورودی فقط یک خروجی دارد. پایتون هم همین قاعده را رعایت می‌کند، ولی با یک ترفند: چند مقدار را در قالب یک تاپل برمی‌گرداند:

def min_max(a, b, c):
    smallest = min(a, b, c)
    largest = max(a, b, c)
    return smallest, largest

result = min_max(7, 2, 9)
print(result)            # (2, 9) ← یک تاپل

lo, hi = min_max(7, 2, 9)
print(lo, hi)            # باز کردن تاپل در دو متغیر

این همان ترفندی است که در جابه‌جایی دو متغیر با x, y = y, x دیدیم.

چه وقت print، چه وقت return؟

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

تمرین

خروجی این کد چیست؟ اول حدس بزنید.

def f(x):
    if x > 0:
        return "positive"
    elif x < 0:
        return "negative"

print(f(5))
print(f(-5))
print(f(0))
جواب

positive، negative و None. برای x = 0 هیچ‌کدام از شرط‌ها درست نیست، پس اجرا بدون رسیدن به هیچ returnی به آخر تابع می‌رسد و None برگردانده می‌شود. برای درست کردنش یک return "zero" آخر تابع اضافه کنید.