Вы написали код на python, запустили его, но терминал продолжает упрямо игнорировать ваши функции и показывает None? Во всём виноват return.
Сегодня разберёмся, что такое оператор return, зачем он нужен, чем отличается от print() и почему, без него ваши функции в коде могут работать неправильно.
Что такое return в Python
Определение оператора return
Return в Python — это оператор, который завершает выполнение функции и передаёт значение обратно в вызывающий код. Без return функция возвращает пустое значение — None. С помощью return можно передавать числа, строки, списки, объекты или даже другие функции.
Представим, что мы заказали еду на дом. В ресторане её приготовили, упаковали, положили в нужное место, и … выбросили. Повар выполнил свою работу, но мы остались без заказа. Нужен кто-то, кто сохранит еду и доставит её нам домой.
Если применять данную аналогию к функциям в Python, тот этот кто-то — оператор return. Он принимает значение функции и передаёт его дальше.
Чем return отличается от print()
Return и print() — это совершенно разные команды, но начинающие разработчики часто их путают.
Отличие в том, что print() показывает значение для пользователя, на экране устройства, но не передаёт его в другие участки кода. А вот return отдаёт само значение программе, чтобы с ним можно было работать дальше и завершает функцию.
# функция отдаёт текст через return, но не выводит его на экран
def get_status():
return "Заказ доставлен!"
# вызываем функцию (результат передался программе, но на экране будет пусто)
get_status()
# print() выводит на экран текст: Заказ доставлен!
print(get_status())
Синтаксис оператора return
Базовый синтаксис
Оператор return всегда пишется внутри функции, с отступом. Он состоит из двух частей: ключевого слова return и значения, которое нужно передать:
def get_number():
return 42
Return принимает значения разных типов, это могут быть строки, числа, словари, кортежи, другие функции и булевые значения:
def is_adult(age):
# Проверяем условие и возвращаем булево значение
if age >= 18:
return True
Return без значения (None)
Даже если не написать оператор return, функция всё равно отдаст результат. Python невидимо для разработчика возвращает значение None в конце любого блока функции.
В этом примере в функции show_message() не указан оператор return, поэтому переменная result получит значение None и выведет его при вызове print():
def show_message(text):
print("Важное сообщение:", text)
# Здесь Питоном невидимо подставлен return None
# Вызываем функцию и пытаемся сохранить её результат
result = show_message("Система обновлена")
# Выведет: None
print("Что вернула функция:", result)
Если мы добавим в функцию оператор return, но, не пропишем ему значение, тоже получим None:
def show_message(text):
print("Важное сообщение:", text)
# Явно пишем пустой return
return
# Вызываем функцию и пытаемся сохранить её результат
result = show_message("Система обновлена")
# Выведет: None
print("Что вернула функция:", result)
Полезный блок со скидкой
Пока функция ещё не вернула None — самое время освоить что-то новое в ИТ. Держите промокод Практикума на любой платный курс: KOD (можно просто нажать). Он даст скидку при покупке и позволит сэкономить на обучении.
Бесплатные курсы в Практикуме тоже есть — по всем специальностям и направлениям, начать можно в любой момент, карту привязывать не нужно, если что.
Return нескольких значений
Оператор return позволяет вернуть несколько значений через запятую: функция автоматически упаковывает их в кортеж — неизменяемую структуру, которую можно распаковать при вызове.
def get_user_stats():
level = 42
health = 100
# Отдаем сразу два значения
return level, health
Как работает return в Python
Пошаговый разбор: вызов → выполнение → возврат
Return не только возвращает вывод функции, но и выступает в роли рубильника, который помогает управлять кодом.
У Python есть интерпретатор — это программа, которая берёт ваш код, переводит его в байт-код и выполняет по частям.
Как только python доходит до функции, он ставит внешний код на паузу, вызывает функцию, выполняет команды внутри неё и ждёт результат вывода.
Когда вывод готов, интерпретатор завершает функцию и продолжает выполнять внешний код:
# 1. Программа идёт сверху вниз и создаёт переменные
first = 10
second = 5
# 2. Python видит функцию, запоминает её, но внутрь пока не заходит
def calculate_sum(a, b):
# 4. Программа перепрыгнула сюда. Выполняем сложение и возвращаем ответ
return a + b
# 3. А вот здесь происходит ВЫЗОВ.
# Основной код ставится на паузу, программа уходит внутрь функции calculate_sum
total_sum = calculate_sum(first, second)
# 5. ВОЗВРАТ. Функция отдала число 15, закрылась, а пауза снялась.
print("Итог:", total_sum)
Такой подход экономит ресурсы, обрабатывать куски кода проще, чем сразу весь код, и return в этом помогает. Он сообщает программе, что функция завершилась, можно перестать её выполнять и переходить к следующему участку.
Стек вызовов и выход из функции
Иногда функция внутри себя может вызывать другие функции, интерпретатору нужно чётко понимать маршрут: кто кого вызвал и куда именно нужно вернуть ответ после завершения работы. Этот маршрут называется стеком вызовов (call stack).
При вызове return, Python немедленно останавливает выполнение функции, возвращает указанное значение вызывающей функции и освобождает локальный стек вызовов — и именно поэтому важно понимать, как устроены функции в Python в целом.
Он помогает Python понять, куда нужно вернуть управление и значение после return.
Рассмотрим на примере:
def add_bonus(score):
# 3. Выполняется внутренняя функция.
# Её return отдаст результат на шаг назад — в calculate_total
return score + 50
def calculate_total(score):
# 2. Внешняя функция тоже ставится на паузу!
# Она вызывает add_bonus и ждёт, пока та отдаст результат
final_score = add_bonus(score)
# 4. Внутренняя функция отработала.
# Теперь внешняя функция делает свой return в основной код
return final_score
# 1. Главный код вызывает функцию и замирает
result = calculate_total(100)
# 5. Все функции закрылись по очереди. Выводим: 150
print("Итоговый счёт:", result)
- Python проходит по коду, запоминает, что мы создали функции add_bonus() и calculate_total().
- Доходит до result = calculate_total(100), добавляет функцию calculate_total() в стек и вызывает её.
- Внутри calculate_total() доходит до функции add_bonus(), добавляет её в стек.
- Ставит на паузу calculate_total() и вызывает add_bonus().
- Выполняет функцию add_bonus(), завершает её и, при помощи return, передаёт значение в calculate_total(), снимает эту функцию с паузы.
- Выполняет calculate_total(), передаёт значение в result.
- Выводит result при помощи print.
Практические примеры использования return
Мы полностью разобрали теорию, как работает оператор return, самое время открыть IDE и попрактиковаться на гоблинах. Для этого напишем несколько функций для максимально простой RPG игры.
Пример 1 — простой возврат числа
Действовать будем от лица рыцаря. Как у любого персонажа в игре, он должен наносить какой-то урон. Напишем функцию, которая возвращает число урона.
def get_damage():
return 15
Сейчас эта функция передаёт значение урона, но ничего не выводит на экран. Чтобы это исправить, мы можем вызвать функцию при помощи кода:
# наносим первый удар
print("Урон за удар:", get_damage())
В реальном проекте выводить функцию сразу после её объявления не лучшая практика. Так, ваш код становится более хаотичным и плохо читаемым. Поэтому иногда лучше объявлять функции в одном месте, а выводить в другом.
Пример 2 — возврат строки
Наш рыцарь не бьёт молча, ему нужна веская причина для драки. Для этого добавим функцию, которая возвращает боевой клич в виде строки.
def get_cry():
return "Отдай мой пирожок!"
Пример 3 — условный return
Добавим ещё один параметр для нашего героя, который отвечает за выносливость. Если она меньше 10, то return вернёт текст, о том, что рыцарь не вступает в бой. В противном случае программа получит сообщение о готовности.
def check_stamina(stamina):
if stamina < 10:
return "Рыцарь устал и ушёл спать."
return "К бою готов!"
Пример 4 — return нескольких значений через кортеж
В случае победы героя, он должен получить лут. Для такого случая напишем функцию, которая возвращает кортеж при помощи return.
def get_loot():
# сохраняем добычу в отдельные переменные
gold = "5 монет"
gear = "Дырявый носок"
# возвращаем сразу обе переменные через запятую
return gold, gear
Пример 5 — return в рекурсивной функции
Теперь напишем функцию, которая наносит урон гоблину до тех пор, пока его здоровье не упадёт до нуля. Сделаем это при помощи рекурсии.
def hit_goblin(hp):
if hp == 0:
return "Гоблин устал танцевать сальсу и сдался!"
# вызываем эту же функцию, отнимая 1 единицу здоровья
return hit_goblin(hp - 1)
Рекурсия — это приём, при котором функция вызывает саму себя. Если такую функцию вовремя не остановить, то она будет вызывать сама себя бесконечно и потреблять много ресурсов компьютера. В таких случаях поможет return, он выступает как точка выхода, после которой функции не надо вызывать саму себя.
Вызываем функции
В первом примере мы уже выяснили, что для читаемости кода функции лучше объявлять в одном месте, а вызывать в другом. Мы написали основные функции, теперь самое время их вызвать и посмотреть на вывод.
# кричим боевой клич
print("Рыцарь кричит:", get_cry())
# проверяем силы перед боем (передаём 20 единиц)
print("Статус:", check_stamina(20))
# наносим удар
print("Урон за удар:", get_damage())
# запускаем серию ударов (у гоблина 3 hp)
print("Итог боя:", hit_goblin(3))
# собираем лут в одну переменную, чтобы показать кортеж
dropped_loot = get_loot()
print("Из гоблина выпало:", dropped_loot)
Вывод:
def get_damage():
return 15
def get_cry():
return "Отдай мой пирожок!"
def check_stamina(stamina):
if stamina < 10:
return "Рыцарь устал и ушёл спать."
return "К бою готов!"
def get_loot():
# сохраняем добычу в отдельные переменные
gold = "5 монет"
gear = "Дырявый носок"
# возвращаем сразу обе переменные через запятую
return gold, gear
def hit_goblin(hp):
if hp == 0:
return "Гоблин устал танцевать сальсу и сдался!"
# вызываем эту же функцию, отнимая 1 единицу здоровья
return hit_goblin(hp - 1)
# === ЗАПУСК ИГРЫ ===
# кричим боевой клич
print("Рыцарь кричит:", get_cry())
# проверяем силы перед боем (передаём 20 единиц)
print("Статус:", check_stamina(20))
# наносим удар
print("Урон за удар:", get_damage())
# запускаем серию ударов (у гоблина 3 hp)
print("Итог боя:", hit_goblin(3))
# собираем лут в одну переменную, чтобы показать кортеж
dropped_loot = get_loot()
print("Из гоблина выпало:", dropped_loot)
Сравнение: return и yield
Кроме return, в Python есть ещё одна команда, которая отдаёт значение функции. Эта команда называется yield. В отличие от return она отдаёт результат функции, но не завершает её, а ставит на паузу, до следующего вызова. Yield используют для выдачи значений пошагово, например, через цикл.
def yield_numbers():
# Отдали единицу и замерли
yield 1
# При следующем запросе проснёмся и отдадим двойку
yield 2
# И так далее
yield 3
# Чтобы получить значения из генератора, их нужно перебрать (например, циклом)
for number in yield_numbers():
print(number)
С return так не получится, функция прекратит выполнения сразу после первого оператора return:
def return_numbers():
# Отдали единицу и навсегда вышли из функции
return 1
# До этой строчки интерпретатор никогда не дойдёт
return 2
# И до этой тоже
return 3
# Вызываем функцию
result = return_numbers()
# Выведет только 1
print(result)
Yield помогает экономить память. Представьте, если наш return должен вернуть миллион значений. Скорее всего, это сильно нагрузит систему. Но если использовать yield, то эти значения можно выводить не сразу, а по очереди. Так, мы сбережём ресурсы компьютера.
Типичные ошибки при использовании return
Ошибка 1. Код после return
Самая частая проблема — попытаться сделать что-то внутри функции уже после того, как сработал return.
Оператор return — это рубильник. Как только Python доходит до этой строчки, он забирает значение и навсегда закрывает функцию. Любой код, написанный ниже, просто никогда не выполнится.
Ошибка 2. Забытый return
Иногда функция делает сложные вычисления, но в основной программе результат почему-то равен None. Чаще всего это значит, что return забыли написать в конце. Похожая история возникает с UnboundLocalError: когда переменная внутри функции не доступна снаружи без явной передачи.
Ошибка 3. return внутри цикла с ранним выходом
Эта ошибка часто возникает при работе со списками. Допустим, нам нужно перебрать список чисел и вернуть их сумму. Если поставить return внутри цикла с тем же отступом, функция прервётся на самом первом шаге.
Ошибка 4. Неправильные отступы
В Python отступы решают всё. return может существовать только внутри функции (то есть должен быть сдвинут вправо как минимум на один Tab).
Если случайно удалить отступ и прижать return к левому краю, интерпретатор просто не поймёт, к чему относится эта команда, и программа вообще не запустится.
Вы не спрашивали, но мы ответим
Что происходит, если не написать return в функции Python?
Если функция не содержит оператора return или он написан без явного указания значения, интерпретатор Python автоматически подставит return None в самый конец блока кода. В этом случае функция выполнит код, но вернёт пустое значение.
Чем отличается return от print() в Python?
Функция print() только выводит текстовые данные на экран монитора для пользователя, но программа их не сохраняет. Оператор return возвращает данные самой программе, позволяя записать результат в переменную или передать его в другую часть кода.
Можно ли написать несколько return в одной функции?
Да. Обычно это делают с помощью условий if/else. Как только сработает первый подходящий return, функция отдаст результат и сразу завершит работу. До остальных вариантов очередь просто не дойдёт.
Что такое return None в Python?
Return None — это команда, которая завершает функцию и возвращает специальный объект — None, он означает отсутствие значения. Его часто используют для досрочного выхода из функции,например, если на вход поступили неверные данные и продолжать вычисления нет смысла.
Бонус для читателей
Если вам интересно писать код и вы хотите разобраться, какой язык программирования выбрать для старта, — держите промокод Практикума на любой платный курс: KOD (можно просто нажать). Он даст скидку при покупке и позволит сэкономить на обучении.
Бесплатные курсы в Практикуме тоже есть — по всем специальностям и направлениям. Начать можно в любой момент, карту привязывать не нужно.
