برنامه‌نویسی پایتون فهرست مطالب
فصل ۱۱

توابع

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

در این فصل می‌خوانید
  1. چرا تابع
  2. اولین تابع
  3. پارامتر و آرگومان
  4. دستور return
  5. تابع بدون return و مقدار None
  6. تابعی که تصمیم می‌گیرد
  7. برگرداندن مقدار بولی
  8. تابع تشخیص عدد اول
  9. استفاده از تابع در حلقه
  10. تابعی که تابع دیگر را صدا می‌زند
  11. کجا تابع را تعریف کنیم

۱. چرا تابع

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

تابع سه چیز به شما می‌دهد:

۲. اولین تابع

# 'def' defines a function. The body is indented, exactly like a loop body.
# Defining a function does NOT run it.
def hello():
    print('Hello World!')

# The function only runs when we CALL it, with parentheses.
hello()
hello()
hello()

اولین تابع: نمونه 01_first_function.py

Hello World!
Hello World!
Hello World!

شرح مثال

۳. پارامتر و آرگومان

تابعی که همیشه یک کار ثابت انجام دهد محدود است. با پارامتر می‌شود به تابع اطلاعات داد.

# A parameter is a variable that receives a value when the function is called.
def hello(name):
    print('Hello', name)

# 'Matin', 'Maryam' and 'Raha' are the arguments.
hello('Matin')
hello('Maryam')
hello('Raha')

# A function may have several parameters; their ORDER matters.
def introduce(name, city):
    print(f'{name} lives in {city}.')

introduce('Ali', 'Rasht')

پارامترها: نمونه 02_parameters.py

اصطلاحیعنیدر مثال
پارامترنام متغیر در تعریف تابعname
آرگومانمقدار واقعی موقع صدا زدن'Matin'

ترتیب آرگومان‌ها مهم است. اگر بنویسید introduce('Rasht', 'Ali')، تابع می‌گوید «Rasht در Ali زندگی می‌کند». پایتون نمی‌فهمد اشتباه کرده‌اید. در فصل بعد راهی می‌بینید که این خطا را از بین می‌برد.

۴. دستور return

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

# 'return' sends a value back to the place where the function was called.
def add(number1, number2):
    total = number1 + number2
    return total

# The returned value can be stored ...
c = add(3, 2)
print(c)

d = add(7, 4)
print(d)

# ... or used directly.
print(add(3, 2))
print(add(1, 2) + add(3, 4))

# 'return' also ENDS the function immediately.
def first_positive(a, b):
    if a > 0:
        return a
    return b            # only reached when a is not positive

print(first_positive(-5, 8))

برگرداندن مقدار: نمونه 03_return.py

5
11
5
10
8

شرح مثال

۵. تابع بدون return و مقدار None

# A function that only prints does NOT give a value back:
# its result is the special value None.
def show_sum(a, b):
    print(a + b)

result = show_sum(2, 3)
print(result)            # None

# A function that returns can be reused in other calculations.
def get_sum(a, b):
    return a + b

result = get_sum(2, 3)
print(result * 10)       # 50

# Rule of thumb: compute with 'return', display with 'print' - not both.

print در برابر return: نمونه 04_return_none.py

5
None
50
مهم‌ترین سوءتفاهم این فصل

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

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

۶. تابعی که تصمیم می‌گیرد

# A function that compares two numbers and returns the bigger one.
# (Python already has max(); we write it here to practise.)
def bigger(num1, num2):
    if num1 > num2:
        return num1
    return num2

user_input = input('Enter the first number: ')
a = float(user_input)

user_input = input('Enter the second number: ')
b = float(user_input)

print('Max:', bigger(a, b))

بزرگ‌تر از دو عدد: نمونه 05_max_of_two.py

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

۷. برگرداندن مقدار بولی

# Three ways of writing the same function, from the longest to the shortest.

def is_even_v1(number):
    if number % 2 == 0:
        return True
    else:
        return False

def is_even_v2(number):
    if number % 2 == 0:
        return True
    return False            # the else is not needed: return already exits

def is_even_v3(number):
    return number % 2 == 0  # the comparison IS already True or False

number = 4

# A function that returns a bool can be used directly inside an if.
if is_even_v3(number):
    print('Even')
else:
    print('Odd')

print(is_even_v1(7), is_even_v2(7), is_even_v3(7))

سه سبک نوشتن یک تابع: نمونه 06_is_even.py

شرح مثال

۸. تابع تشخیص عدد اول

# The prime test of session 08, turned into a reusable function.
def is_prime(number):
    # 0, 1 and the negative numbers are not prime.
    if number < 2:
        return False

    for i in range(2, number):
        if number % i == 0:
            return False     # a divisor was found -> stop immediately

    return True              # no divisor was found

user_input = input('Enter a number: ')
n = int(user_input)

if is_prime(n):
    print('Prime!')
else:
    print('Not prime.')

# The same function on a whole list of numbers.
numbers = [13, 11, 6, 8, 2, 7, 21, 1, 0, -3]
for num in numbers:
    print(num, is_prime(num))

تابع عدد اول: نمونه 07_is_prime.py

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

۹. استفاده از تابع در حلقه

# Once the function exists, answering a bigger question is easy.
def is_prime(number):
    if number < 2:
        return False
    # Testing up to the square root is enough: a divisor bigger than the root
    # always has a partner smaller than the root.
    i = 2
    while i * i <= number:
        if number % i == 0:
            return False
        i += 1
    return True

count = 0

for number in range(50000, 100000):
    if is_prime(number):
        count += 1

print('Number of primes between 50000 and 100000:', count)

شمردن اعداد اول: نمونه 08_count_primes.py

شرح مثال

۱۰. تابعی که تابع دیگر را صدا می‌زند

# A function may call another function. Here pow() is built on top of mul().
def mul(num1, num2):
    'Multiply two whole numbers using repeated addition.'
    result = 0
    for i in range(num2):
        result += num1
    return result

def power(num1, num2):
    'Raise num1 to the power num2 using repeated multiplication.'
    result = 1
    for i in range(num2):
        result = mul(result, num1)
    return result

a = int(input('Enter the base: '))
b = int(input('Enter the exponent: '))

print(power(a, b))

تابع روی تابع: نمونه 09_function_calls_function.py

شرح مثال

۱۱. کجا تابع را تعریف کنیم

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

# Right: define first, call later.
def greet(name):
    return f'Hello {name}'

print(greet('Ali'))


# Wrong: this would raise NameError, because greet2 does not exist yet.
# print(greet2('Ali'))
# def greet2(name):
#     return f'Hello {name}'

ترتیب تعریف و صدا زدن

استثنا: یک تابع می‌تواند تابعی را صدا بزند که پایین‌تر تعریف شده است، به شرطی که موقع اجرا هر دو تعریف شده باشند. چون بدنه تابع فقط هنگام صدا زدن اجرا می‌شود، نه هنگام تعریف. در فصل بعد با الگوی main() این را مرتب می‌کنیم.

فایل‌های تمرینی این فصل

پوشه S11-functions-basics شامل نمونه‌های 01_first_function.py تا 10_multiplication.py.

خلاصه فصل

ابزاروظیفه آن
def name():تعریف تابع. اجرا نمی‌شود تا صدا زده شود
name()صدا زدن تابع
پارامترمتغیر داخل تعریف تابع
آرگومانمقدار واقعی موقع صدا زدن
return xپس دادن نتیجه و تمام کردن فوری تابع
Noneنتیجه تابعی که return ندارد
return a == bراه پایتونی برگرداندن بولی
is_ در نامقرارداد نام‌گذاری توابعی که بولی برمی‌گردانند
ترتیب تعریفتابع باید پیش از صدا زده شدن تعریف شده باشد

تمرین‌های فصل یازده

  1. تابع square(n) را بنویسید که مربع یک عدد را برگرداند.
  2. تابع celsius_to_fahrenheit(c) را بنویسید و با سه مقدار امتحانش کنید.
  3. تابع is_leap(year) را بنویسید که برای سال کبیسه True برگرداند.
  4. تابع count_vowels(text) را بنویسید که تعداد حروف صدادار یک جمله را برگرداند.
  5. تابع average(a, b, c) را بنویسید که میانگین سه عدد را برگرداند.
  6. تابع factorial(n) را بنویسید و با آن ترکیب C(n, k) = n! / (k! * (n-k)!) را حساب کنید.
  7. تابع reverse_text(text) را بدون استفاده از برش بنویسید.
  8. تابع is_palindrome(text) را با کمک تابع تمرین قبل بنویسید.
فصل قبل: الگوریتم‌های لیست فصل بعد: آرگومان‌ها و حوزه متغیر