Перейти к содержимому
Теория · Первая программа · урок 5 из 7

Первая функция

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

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

Python
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): начинает определение функции. Она собирается так:

  1. Слово def говорит, что дальше идёт новая функция.
  2. add — её имя, по нему функцию вызывают.
  3. В скобках перечислены входные данные a и b.
  4. Двоеточие открывает блок — тело функции, сдвинутое на 4 пробела.

После определения функции по PEP 8, общепринятым правилам оформления кода на Python, оставляют две пустые строки.

Параметры и аргументы

В скобках после имени стоят параметры — имена, которые получают значения при вызове. В вызове add(2, 3) аргументы 2 и 3 попадают в параметры a и b по порядку. Число аргументов должно совпадать с числом параметров.

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

Слово return

Слово return завершает функцию и возвращает значение выражения после него. Выражение — это код, который даёт значение, например a + b. Сам вызов заменяется возвращённым значением, поэтому его можно передать в print.

Функция add сама ничего не печатает. Она возвращает значение на место вызова, а печатает его print, внутри которого стоит вызов.

Когда выполняется тело

Строка с def только создаёт функцию, а её тело выполняется при каждом вызове. Файл выполняется сверху вниз, поэтому определение должно стоять выше первого вызова. Если вызвать функцию раньше, чем до неё дошёл интерпретатор, программа остановится на этом вызове с ошибкой NameError.

Здесь аналогия с рецептом перестаёт работать. Повар может заглянуть в любую страницу книги рецептов, даже в последнюю. Интерпретатор знает только те функции, чьи строки def он уже выполнил.

Нажимайте «Следующий шаг» и следите, когда интерпретатор заходит в тело add и на какой строке программа останавливается.

ВживуюСверху вниз: def, вызов и ошибкашаг 1 из 6 · рамок: 1

Строка def создаёт функцию add, но её тело пока не выполняется.

Подсвеченная строка выполняется сейчас, а рамки — вызовы, которые ждут результата

Программа напечатала start и 5, а потом остановилась с ошибкой NameError: name 'double' is not defined. Строки ниже седьмой не выполнились, поэтому функция double так и не была создана. Перенесите её определение выше вызова, и программа напечатает ещё 8.

Порядок вычислений

С числами работают операторы +, - и *; * означает умножение. Как в математике, * выполняется раньше + и -, а скобки меняют этот порядок. Вызов функции тоже может быть аргументом другого вызова. Тогда сначала выполняется внутренний вызов, и его результат попадает во внешний.

Python
print(1 + 2 * 3)  # 7
print((1 + 2) * 3)  # 9
print(add(add(1, 2), 3))  # 6
print(add(1, 2) * 10)  # 30

Давайте разберём две последние строки:

  1. В третьей строке add(1, 2) возвращает 3, затем add(3, 3) возвращает 6, и печатается только 6.
  2. В четвёртой строке вызов тоже выполняется первым: add(1, 2) даёт 3, и только потом 3 * 10 даёт 30.

Частая ошибка

Тело функции написано без отступа:

Python
def add(a, b):
return a + b  # ✗
TEXT
IndentationError: expected an indented block after function definition on line 1

После строки с двоеточием интерпретатор ждёт блок со сдвигом вправо. Но следующая строка начинается с первого символа. Ошибку находит проверка файла, поэтому программа не выполняет ни одной строки. Исправление — сдвинуть return a + b на 4 пробела, как в первом примере.

Главное

  • def с именем, параметрами и двоеточием создаёт функцию, а её тело выполняется при каждом вызове.
  • Параметр — имя в определении, аргумент — значение в вызове.
  • return возвращает значение, и оно встаёт на место вызова.
  • Определение должно стоять выше первого вызова: иначе программа остановится на вызове с NameError.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом