
Функции в Python: параметры и return
Разделяем программу на небольшие операции, передаём данные через параметры, возвращаем результат и избегаем скрытой зависимости от глобальных переменных.
Содержание
Функция объединяет одно законченное действие под понятным именем. Вместо повторения формулы в нескольких местах программа вызывает одну реализацию. Параметры передают входные данные, а return возвращает вычисленный результат.
До этого урока нужны условия и циклы. Примеры выполняют расчёты в памяти.
Определение не равно вызову
Создайте functions.py. Следующий код сначала определяет функцию, затем вызывает её и печатает результат:
def calculate_delivery(order_total):
if order_total >= 3000:
return 0
return 350
delivery_price = calculate_delivery(2500)
print(delivery_price)
Слово def начинает определение, calculate_delivery — имя, а order_total — параметр. Само определение не выполняет расчёт. Вызов calculate_delivery(2500) передаёт аргумент 2500, функция возвращает 350, и это число сохраняется в delivery_price.
Две пустые строки между функцией и основным кодом — рекомендация стиля, а не условие выполнения. Тело функции отмечено отступом.
return завершает текущий вызов
При сумме 3200 выполняется первый return 0, после чего функция заканчивается и до return 350 не доходит. Такая ранняя отдача результата позволяет сначала закрыть особый случай, а основной оставить без лишнего else.
print не заменяет return. Если функция только напечатает 350, переменная с результатом получит None. Печатать лучше на границе программы, а внутри возвращать данные: тогда вычисление можно использовать в веб-приложении, тесте и консольном инструменте без переписывания.
Несколько параметров делают зависимости явными
Порог и обычный тариф не должны быть скрыты внутри формулы, если разные вызовы используют разные условия. Передадим их отдельно:
def calculate_delivery(order_total, free_from, regular_price):
if order_total >= free_from:
return 0
return regular_price
price = calculate_delivery(2500, 3000, 350)
print(price)
Результат снова равен 350. Позиционные аргументы сопоставляются параметрам слева направо. Если случайно поменять 3000 и 350 местами, код останется допустимым, но смысл нарушится.
Именованные аргументы показывают назначение прямо в вызове:
price = calculate_delivery(
order_total=2500,
free_from=3000,
regular_price=350,
)
Этот вызов возвращает то же значение. Завершающая запятая в многострочной записи упрощает будущие изменения. После первого именованного аргумента не добавляйте обычный позиционный: такой порядок вызывает SyntaxError.
Значение по умолчанию подходит только для устойчивого правила
Если обычная доставка почти всегда стоит 350, параметру можно задать значение по умолчанию:
def calculate_delivery(order_total, free_from, regular_price=350):
if order_total >= free_from:
return 0
return regular_price
print(calculate_delivery(2200, 3000))
print(calculate_delivery(2200, 3000, regular_price=500))
Первая строка вывода — 350, вторая — 500. Параметр со значением по умолчанию должен располагаться после обязательных параметров. Не используйте изменяемый список или словарь как значение по умолчанию: один объект сохранится между вызовами и накопит неожиданные изменения.
Одна функция должна иметь ясный результат
Функция process_order, которая одновременно читает файл, считает доставку, меняет базу и отправляет письмо, трудно проверяется и возвращается после ошибки. Разделите её на небольшие операции с явными входами и выходами.
Хорошее имя начинается с действия: calculate_total, load_config, is_port_allowed. Префикс is уместен для логического ответа. Название do_data почти ничего не объясняет.
Добавьте строку документации сразу под def, если назначение и ограничения неочевидны:
def calculate_delivery(order_total, free_from, regular_price=350):
"""Вернуть стоимость доставки для неотрицательной суммы заказа."""
if order_total >= free_from:
return 0
return regular_price
Тройная строка называется docstring. Её видит help(calculate_delivery) и инструменты документации. Она описывает договор функции, а не пересказывает каждую строку.
Проверяйте входные условия рядом с функцией
Текущая реализация примет отрицательную сумму и вернёт обычный тариф, хотя данные неверны. Временно можно явно остановить расчёт:
def calculate_delivery(order_total, free_from, regular_price=350):
if order_total < 0:
raise ValueError("Сумма заказа не может быть отрицательной")
if order_total >= free_from:
return 0
return regular_price
raise создаёт исключение ValueError и прекращает текущий вызов. Это не «поломка Python», а сигнал вызывающему коду о недопустимом значении. В следующем уроке программа обработает ожидаемое исключение и покажет понятный ответ пользователю.
Избегайте скрытого глобального состояния
Функция может читать имя, созданное вне неё, но результат становится зависимым от окружающего файла. Передавайте необходимые значения параметрами. Так каждый вызов самодостаточен, а тесту не нужно заранее менять глобальные переменные.
Локальные имена внутри функции не доступны снаружи после её завершения. Это полезная граница: промежуточные детали не засоряют остальную программу. Верните только то, что действительно нужно следующему шагу.
Дальше — обработка ошибок и исключений. Полный синтаксис параметров и функций разобран в официальном разделе Defining Functions.
Самопроверка
Проверьте, что материал усвоен
Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.
Разбираем коротко
Частые вопросы
Чем print отличается от return?
print показывает значение человеку, а return передаёт результат вызывающему коду. Напечатанное значение нельзя удобно использовать в следующем вычислении.
Обязаны ли параметры совпадать с именами аргументов?
Нет. Параметр — имя внутри определения функции, аргумент — переданное при вызове значение. Имена могут различаться, если вызов не использует именованный аргумент.
Что возвращает функция без return?
Она возвращает None. Это нормальное поведение для операции, результат которой не требуется, но может скрыть ошибку, если вызывающий код ожидал число или строку.


