Part 4

Еще о функциях

Кратко повторим функции Python. Функции определяются с помощью ключевого слова def:

def message():
    print("This message was brought to you by a function")

Эту функцию можно вызвать в коде программы так:

message()

Тогда ваша программа выведет

Пример вывода

This message was brought to you by a function

Параметры и аргументы функции

Функция может принимать один или несколько аргументов. Когда функция вызывается, аргументы присваиваются переменным, которые определены в определении функции. Эти переменные называются параметрами, и они перечисляются внутри круглых скобок после имени функции.

В следующем коде у функции greet определен один параметр, а у функции sum - два.

def greet(name):
    print("Hello there,", name)

def sum(a, b):
    print("The sum of the arguments is", a + b)
greet("Emily")
sum(2, 3)
Пример вывода

Hello there, Emily The sum of the arguments is 5

Сообщения об ошибках при запуске тестов

К большинству упражнений этого курса прикреплены автоматические тесты. Если ваша программа не работает так, как указано в задании, тесты покажут сообщение об ошибке, которое может быть полезным, а может и не быть. Обычно стоит внимательно прочитать сообщение об ошибке.

В некоторых ситуациях сообщение об ошибке может почти ничего не объяснять. В следующем упражнении ниже вы можете встретить такое сообщение:

4 2 1

Сообщение лишь говорит, что должна быть возможность вызвать функцию line с указанными аргументами:

line(5, "")

Настоящая проблема становится понятной, когда мы пробуем выполнить вызов функции, указанный в сообщении об ошибке. Это можно сделать, скопировав вызов функции в свою программу и нажав на треугольник:

4 2 2

Последние строки, созданные выполнением и выделенные на изображении выше, говорят нам, что строка 4 нашего кода вызывает ошибку IndexError: string index out of range. В предыдущей части был похожий пример, где мы пытались использовать индекс, выходящий за пределы строки. В этот раз ошибка появляется потому, что мы пытаемся обратиться к первому символу пустой строки, то есть строки длиной 0.

Loading

Вызовы функций внутри вызовов функций

Вы можете вызвать функцию изнутри другой функции. На самом деле мы уже много раз так делали, когда вызывали функцию print внутри собственных функций в предыдущей части. Наши собственные функции функционально ничем не отличаются. В следующем примере функция greet_many_times вызывает функцию greet столько раз, сколько указано аргументом times:

def greet(name):
    print("Hello there,", name)

def greet_many_times(name, times):
    while times > 0:
        greet(name)
        times -= 1

greet_many_times("Emily", 3)
Пример вывода

Hello there, Emily Hello there, Emily Hello there, Emily

Loading
Loading
Loading
Loading
Loading
Loading

Возвращаемое значение функции

Функции также могут возвращать значения. Например, встроенная функция Python input возвращает строку ввода, набранную пользователем. Значение, возвращенное функцией, можно сохранить в переменной:

word = input("Please type in a word: ")

Когда вам нужно получить от пользователя целочисленное значение, ввод пользователя нужно преобразовать в целое число. Функция, которую мы использовали для этой цели, - int, и она тоже возвращает значение:

number = int(input("Please type in an integer: "))

Функция int принимает строку, возвращенную input, как свой аргумент и возвращает значение целочисленного типа, если из строки можно разобрать целое число.

Инструкция return

Функции, которые вы определяете сами, тоже могут возвращать значения. Для этого нужна инструкция return. Например, следующая функция my_sum возвращает сумму своих параметров:

def my_sum(a, b):
    return a + b

result = my_sum(2, 3)

print("Sum:", result)
Пример вывода

Sum: 5

Вот еще один пример возвращаемого значения. Эта функция спрашивает имя пользователя и возвращает строку, которую пользователь набирает:

def ask_for_name():
    name = input("What is your name? ")
    return name

name = ask_for_name()
print("Hello there,", name)
Пример вывода

What is your name? Anna Hello there, Anna

Инструкция return немедленно завершает выполнение функции. Следующий вариант - аккуратный способ создать функцию сравнения:

def smallest(a,b):
    if a < b:
        return a
    return b

print(smallest(3, 7))
print(smallest(5, 2))

Идея здесь в том, что если a меньше b, функция возвращает a и сразу выходит. Если нет, выполнение продолжается на следующей строке, где возвращается значение b. Функция никогда не может выполнить две отдельные инструкции return за один вызов функции.

Пример вывода

3 2

Инструкцию return можно использовать даже если функция не возвращает значение. Тогда ее цель - завершить выполнение функции:

def greet(name):
    if name == "":
        print("???")
        return
    print("Hello there,", name)

greet("Emily")
greet("")
greet("Mark")

Если аргумент (который сохраняется в переменной name) - пустая строка, функция выводит ??? и выходит.

Пример вывода

Hello there, Emily ??? Hello there, Mark

Использование возвращаемых значений функций

Мы уже знаем, что возвращаемые значения функций можно сохранять в переменных:

def my_sum(a, b):
    return a + b

result = my_sum(4, 6)
print("The sum is", result)
Пример вывода

The sum is 10

Возвращаемое значение функции - такое же значение, как любое другое. Его не обязательно сохранять в переменной, чтобы передать как аргумент команде print:

print("The sum is", my_sum(4, 6))

Возвращаемое значение функции может стать аргументом другой функции:

def my_sum(a, b):
    return a+b

def difference(a, b):
    return a-b

result = difference(my_sum(5, 2), my_sum(2, 3))
print("The result is", result)
Пример вывода

The result is 2

В этом случае сначала выполняются внутренние вызовы функций my_sum(5, 2) и my_sum(2, 3). Значения, которые они возвращают (7 и 5), используются как аргументы внешнего вызова функции.

Внешний вызов функции difference(7, 5) возвращает значение 2, которое сохраняется в переменной result и выводится.

Итак, значения, возвращаемые функциями, работают точно так же, как любые другие значения в Python. Их можно выводить, сохранять в переменных, использовать в выражениях и использовать как аргументы в других вызовах функций.

Разница между return и print

Иногда различие между тем, что функция возвращает значение, и командой print внутри функции может быть неочевидным. Посмотрим на два разных способа реализовать функцию, которая выясняет, какое из двух значений больше:

def max1(a, b):
    if a > b:
        return a
    else:
        return b

def max2(a, b):
    if a > b:
        print(a)
    else:
        print(b)

result = max1(3, 5)
print(result)

max2(7, 2)
Пример вывода

5 7

Обе версии, кажется, работают вполне нормально, поскольку максимальные значения выводятся правильно. Однако между ними есть фундаментальная разница. Первая из двух функций, max1, сама ничего не выводит, а возвращает большее значение. Если выполнить следующую строку

max1(3, 5)

кажется, что ничего не происходит. Возвращаемое значение функции нужно каким-то образом использовать в коде, который вызвал функцию. Например, его можно сохранить в переменной и вывести:

result = max1(3, 5)
print(result)

Вторая версия, max2, использует команду print внутри функции, чтобы вывести большее значение. Если мы хотим увидеть значение, достаточно вызвать функцию

max2(7, 5)

и большее значение будет выведено. Недостаток этой удобной функции в том, что значение, вычисленное функцией, недоступно для использования в программе, которая ее вызвала. Именно поэтому функции, возвращающие значения, часто являются лучшим вариантом.

Loading
Loading
Loading

Тип аргумента

Кратко повторим типы данных, которые мы уже встречали:

ТипТип данных PythonПример
целое числоint23
число с плавающей точкойfloat-0.45
строкаstr"Peter Python"
булево значениеboolTrue

Когда вы вызываете функцию, она будет работать правильно только если переданные ей аргументы имеют подходящий тип. Рассмотрим пример:

def print_many_times(message, times):
    while times > 0:
        print(message)
        times -= 1

Функция работает как ожидается, если вызвать ее так:

print_many_times("Hello there", 5)
Пример вывода

Hello there Hello there Hello there Hello there Hello there

Однако, если передать функции аргумент неправильного типа, она не будет работать:

print_many_times("Hello there", "Emily")
Пример вывода

TypeError: '>' not supported between instances of 'str' and 'int'

Проблема здесь в том, что второй параметр times сравнивается с целым числом, 0, на строке 2 определения функции. Переданный аргумент был "Emily", то есть строка, а не целое число. Строки и целые числа нельзя сравнивать так просто, поэтому возникает ошибка.

Чтобы избежать подобных проблем, можно включать подсказки типов в определения функций. Подсказка типа указывает тип аргумента, предназначенного для функции:

def print_many_times(message : str, times : int):
    while times > 0:
        print(message)
        times -= 1

Это сообщает любому, кто использует функцию, что аргумент, сохраненный в message, должен быть строкой, а аргумент, сохраненный в times, должен быть целым числом.

Аналогично, в определении функции можно подсказать возвращаемое значение:

def ask_for_name() -> str:
    name = input("Mikä on nimesi? ")
    return name

Это сообщает пользователю функции, что функция должна вернуть строку.

Обратите внимание: Подсказки типов буквально являются только подсказками о типе аргумента или возвращаемого значения. Это не гарантия типа и точно не защита от ошибок типов. Если функция получает аргумент или возвращает значение неправильного типа, функция все равно выполняется, но может работать неправильно.

Вы дошли до конца этого раздела! Перейти к следующему разделу:

Текущие баллы можно посмотреть в синем индикаторе в правом нижнем углу страницы.