Перейти к содержимому
Теория · Функции · урок 1 из 8

Параметры и значения по умолчанию

Чему вы научитесь

Чему вы научитесь:

  • задавать параметрам значения по умолчанию и вызывать функцию с разным числом аргументов;
  • передавать аргументы по позиции и по имени;
  • отличать локальные переменные от глобальных и менять глобальную через global;
  • писать рекурсивные функции и понимать, как вызовы ждут друг друга.
Кофемашина total, в щель входит монета, а две ручки уже стоят на count=1 и discount=0

Представьте кофемашину с табличкой total. В щель вы опускаете монету — цену одной чашки. Рядом две ручки: «сколько чашек» и «скидка». Они уже выставлены на count=1 и discount=0, и обычно их никто не трогает.

Хотите три чашки — поворачиваете одну ручку, а скидку оставляете как есть. Без монеты машина не работает. Без поворота ручек работает прекрасно: она берёт то, что на них уже выставлено.

Функции в Python устроены так же. Как вы уже знаете, имена в строке def — это параметры, а значения в вызове — аргументы. Функция total считает стоимость покупки: цену, умноженную на количество, минус скидку. Без настроек каждый вызов передавал бы три числа, даже когда нужна одна чашка без скидки:

Python
def total(price, count=1, discount=0):
    return price * count - discount


print(total(250))  # 250
print(total(250, 3))  # 750
print(total(250, 3, 100))  # 650

Давайте разберём вызовы по строкам:

  1. total(250) передаёт только цену. count берёт 1, discount берёт 0, и функция возвращает 250.
  2. total(250, 3) поворачивает первую ручку: count равен 3, скидка по-прежнему 0. Результат — 750.
  3. total(250, 3, 100) задаёт все три параметра и возвращает 650.

Аргументы по умолчанию

Запись count=1 в строке def задаёт аргумент по умолчанию: если вызов не передал аргумент для count, параметр получает 1. Это и есть заранее выставленная ручка.

Параметр без такого значения обязателен — это монета. Вызов total() без цены остановится с ошибкой:

TEXT
TypeError: total() missing 1 required positional argument: 'price'

Вы уже встречали аргументы по умолчанию у print. У его параметров sep и end есть значения: пробел и переход на новую строку. Поэтому print без них печатает значения через пробел и заканчивает строку.

В строке def параметры со значением по умолчанию пишут после обязательных. Строка def total(price=0, count): не даёт файлу запуститься: SyntaxError: parameter without a default follows parameter with a default.

Два способа передать аргумент

Аргумент можно передать по месту в списке или по имени параметра. Разберём оба способа.

Позиционные аргументы

Аргументы без имени называют позиционными: они заполняют параметры слева направо. В вызове total(250, 3) число 250 попадает в price, 3 — в count, а discount остаётся равным 0.

Пропустить средний параметр так нельзя. Второй позиционный аргумент всегда попадает во второй параметр. Лишний аргумент тоже не пройдёт: вызов total(250, 3, 100, 5) даёт TypeError: total() takes from 1 to 3 positional arguments but 4 were given.

Именованные аргументы

Чтобы передать скидку и оставить количество по умолчанию, аргумент называют по имени параметра. Это именованный аргумент, как sep="-" в вызове print:

Python
print(total(250, discount=50))  # 200
print(total(discount=50, price=250))  # 200
print(total(250, count=2, discount=100))  # 400

Что важно знать об именованных аргументах:

  • их порядок не важен: вторая строка даёт то же, что первая;
  • позиционные аргументы пишут первыми, именованные — после них;
  • один параметр не может получить два значения: total(250, price=300) даёт TypeError: total() got multiple values for argument 'price';
  • имя должно совпадать с именем параметра: опечатка в total(250, cnt=2) даёт TypeError: total() got an unexpected keyword argument 'cnt'.

Здесь аналогия с кофемашиной заканчивается. Ручки на машине можно крутить в любом порядке. У позиционных аргументов порядок строгий, и только имя позволяет «дотянуться» до дальней ручки, не трогая ближнюю.

Когда вычисляется значение по умолчанию

Этот вопрос часто задают на собеседовании. Значение по умолчанию вычисляется один раз — когда Python выполняет строку def. Дальше функция хранит готовое значение, а не выражение:

Python
rate = 10


def with_rate(x=rate):
    return x


rate = 20
print(with_rate())  # 10
print(with_rate(5))  # 5

Разберём по шагам:

  1. Строка def выполняется, когда rate равна 10. Функция запоминает для x значение 10.
  2. rate = 20 меняет переменную, но запомненное значение остаётся прежним.
  3. with_rate() печатает 10, а with_rate(5) — переданное 5.

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

Именованный аргумент поставили перед позиционным:

Python
print(total(price=250, 3))  # ✗
TEXT
SyntaxError: positional argument follows keyword argument

Порядок аргументов проверяется вместе со всем файлом до запуска, поэтому не выполняется ни одна строка. Сначала пишите позиционные аргументы: total(250, 3) или total(250, count=3).

Главное

  • Аргумент по умолчанию задают в def как count=1; такие параметры идут после обязательных.
  • Позиционные аргументы заполняют параметры слева направо, именованные — по имени и в любом порядке.
  • В вызове позиционные аргументы стоят перед именованными, иначе файл не запустится.
  • Значение по умолчанию вычисляется один раз, когда выполняется строка def.

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

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

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