Первая функция
Представьте карточку с рецептом. Рецепт записывают один раз, а готовят по нему сколько угодно: сегодня на двоих, завтра на десятерых. На карточке сказано, что положить, что с этим сделать и какое блюдо получится в конце.
В программе такая карточка — своя функция. Когда одно и то же вычисление нужно в нескольких местах, его записывают один раз и дают ему имя. Функция add получает два числа и возвращает их сумму:
def add(a, b):
return a + b
print(add(2, 3)) # 5
print(add(10, -4)) # 6Здесь рецепт записан в первых двух строках, а готовят по нему дважды: с числами 2 и 3, потом с 10 и -4.
Определение и вызов
Разберём функцию add по частям.
Строка def
Строка def add(a, b): начинает определение функции. Она собирается так:
- Слово
defговорит, что дальше идёт новая функция. add— её имя, по нему функцию вызывают.- В скобках перечислены входные данные
aиb. - Двоеточие открывает блок — тело функции, сдвинутое на 4 пробела.
После определения функции по PEP 8, общепринятым правилам оформления кода на Python, оставляют две пустые строки.
Параметры и аргументы
В скобках после имени стоят параметры — имена, которые получают значения при вызове. В вызове add(2, 3) аргументы 2 и 3 попадают в параметры a и b по порядку. Число аргументов должно совпадать с числом параметров.
На собеседовании любят спрашивать, чем параметр отличается от аргумента. Параметр — имя в определении функции, а аргумент — значение, которое передают при вызове.
Слово return
Слово return завершает функцию и возвращает значение выражения после него. Выражение — это код, который даёт значение, например a + b. Сам вызов заменяется возвращённым значением, поэтому его можно передать в print.
Функция add сама ничего не печатает. Она возвращает значение на место вызова, а печатает его print, внутри которого стоит вызов.
Когда выполняется тело
Строка с def только создаёт функцию, а её тело выполняется при каждом вызове. Файл выполняется сверху вниз, поэтому определение должно стоять выше первого вызова. Если вызвать функцию раньше, чем до неё дошёл интерпретатор, программа остановится на этом вызове с ошибкой NameError.
Здесь аналогия с рецептом перестаёт работать. Повар может заглянуть в любую страницу книги рецептов, даже в последнюю. Интерпретатор знает только те функции, чьи строки def он уже выполнил.
Нажимайте «Следующий шаг» и следите, когда интерпретатор заходит в тело add и на какой строке программа останавливается.
1def add(a, b):2 return a + b3 4 5print("start")6print(add(2, 3))7print(double(4))8 9 10def double(x):11 return x + x
Строка def создаёт функцию add, но её тело пока не выполняется.
Программа напечатала start и 5, а потом остановилась с ошибкой NameError: name 'double' is not defined. Строки ниже седьмой не выполнились, поэтому функция double так и не была создана. Перенесите её определение выше вызова, и программа напечатает ещё 8.
Порядок вычислений
С числами работают операторы +, - и *; * означает умножение. Как в математике, * выполняется раньше + и -, а скобки меняют этот порядок. Вызов функции тоже может быть аргументом другого вызова. Тогда сначала выполняется внутренний вызов, и его результат попадает во внешний.
print(1 + 2 * 3) # 7
print((1 + 2) * 3) # 9
print(add(add(1, 2), 3)) # 6
print(add(1, 2) * 10) # 30Давайте разберём две последние строки:
- В третьей строке
add(1, 2)возвращает3, затемadd(3, 3)возвращает6, и печатается только6. - В четвёртой строке вызов тоже выполняется первым:
add(1, 2)даёт3, и только потом3 * 10даёт30.
Частая ошибка
Тело функции написано без отступа:
def add(a, b):
return a + b # ✗IndentationError: expected an indented block after function definition on line 1После строки с двоеточием интерпретатор ждёт блок со сдвигом вправо. Но следующая строка начинается с первого символа. Ошибку находит проверка файла, поэтому программа не выполняет ни одной строки. Исправление — сдвинуть return a + b на 4 пробела, как в первом примере.
Главное
defс именем, параметрами и двоеточием создаёт функцию, а её тело выполняется при каждом вызове.- Параметр — имя в определении, аргумент — значение в вызове.
returnвозвращает значение, и оно встаёт на место вызова.- Определение должно стоять выше первого вызова: иначе программа остановится на вызове с
NameError.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.