Еще о функциях
Кратко повторим функции 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
Сообщения об ошибках при запуске тестов
К большинству упражнений этого курса прикреплены автоматические тесты. Если ваша программа не работает так, как указано в задании, тесты покажут сообщение об ошибке, которое может быть полезным, а может и не быть. Обычно стоит внимательно прочитать сообщение об ошибке.
В некоторых ситуациях сообщение об ошибке может почти ничего не объяснять. В следующем упражнении ниже вы можете встретить такое сообщение:
Сообщение лишь говорит, что должна быть возможность вызвать функцию line с указанными аргументами:
line(5, "")Настоящая проблема становится понятной, когда мы пробуем выполнить вызов функции, указанный в сообщении об ошибке. Это можно сделать, скопировав вызов функции в свою программу и нажав на треугольник:
Последние строки, созданные выполнением и выделенные на изображении выше, говорят нам, что строка 4 нашего кода вызывает ошибку IndexError: string index out of range. В предыдущей части был похожий пример, где мы пытались использовать индекс, выходящий за пределы строки. В этот раз ошибка появляется потому, что мы пытаемся обратиться к первому символу пустой строки, то есть строки длиной 0.
Вызовы функций внутри вызовов функций
Вы можете вызвать функцию изнутри другой функции. На самом деле мы уже много раз так делали, когда вызывали функцию 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
Возвращаемое значение функции
Функции также могут возвращать значения. Например, встроенная функция 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)и большее значение будет выведено. Недостаток этой удобной функции в том, что значение, вычисленное функцией, недоступно для использования в программе, которая ее вызвала. Именно поэтому функции, возвращающие значения, часто являются лучшим вариантом.
Тип аргумента
Кратко повторим типы данных, которые мы уже встречали:
| Тип | Тип данных Python | Пример |
|---|---|---|
| целое число | int | 23 |
| число с плавающей точкой | float | -0.45 |
| строка | str | "Peter Python" |
| булево значение | bool | True |
Когда вы вызываете функцию, она будет работать правильно только если переданные ей аргументы имеют подходящий тип. Рассмотрим пример:
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Это сообщает пользователю функции, что функция должна вернуть строку.
Обратите внимание: Подсказки типов буквально являются только подсказками о типе аргумента или возвращаемого значения. Это не гарантия типа и точно не защита от ошибок типов. Если функция получает аргумент или возвращает значение неправильного типа, функция все равно выполняется, но может работать неправильно.
Текущие баллы можно посмотреть в синем индикаторе в правом нижнем углу страницы.