Вывод сообщает, возврат передаёт значение
В Python функция print отправляет представление объектов в поток вывода, обычно в консоль. Оператор return завершает выполнение функции и передаёт указанное значение туда, где функция была вызвана. Появление текста на экране само по себе не означает, что вызывающий код получил это число. Представим функцию для вычисления периметра прямоугольника. Её входные данные обозначим width и height. При ширине четыре и высоте семь вычисление даёт двадцать два. Если внутри функции стоит только print от вычисленного значения, человек увидит двадцать два, но функция завершится без явно указанного возвращаемого результата. При таком завершении обычная функция возвращает None. Это специальное значение, а не автоматически сохранённая копия напечатанного числа. Поэтому присваивание результата вызова переменной не восстановит число из консоли.
Сформулируйте договор между частями программы
До написания функции опишите три вещи: какие данные она получает, что вычисляет и что должна вернуть. В нашем примере договор простой: получить две положительные длины и вернуть числовое значение периметра. Показать его пользователю можно отдельно. Внутри функции смысл операции выражается как return 2 * (width + height). После вызова perimeter(4, 7) переменная, которой присвоен результат, получит число двадцать два. Затем к нему можно прибавить три и получить двадцать пять либо передать значение другой функции. Так вычисление становится пригодным для повторного использования. Один участок программы покажет число в консоли, другой включит его в сообщение, третий сравнит с ограничением. Этот учебный договор пока ограничен положительными числами. Он не объясняет, что делать со строкой, отрицательной длиной или отсутствующим аргументом. Такие случаи следует определить отдельно, если функция должна обрабатывать их. Не стоит молча приписывать ей возможности, которых в описании нет.
Проверьте полученное значение, а не только видимый текст
Для проверки полезно отдельно записать ожидаемый результат вызова и ожидаемый вывод. У функции, которая только возвращает периметр, обычный вызов внутри сценария может ничего не показать в консоли. Это не признак отсутствия вычисления: значение можно сохранить и использовать дальше. Интерактивная среда иногда сама отображает значение введённого выражения. Из-за этого новичку кажется, что функция обязательно печатает результат. Чтобы различить действия, посмотрите на её тело: есть ли явный вывод и какое значение возвращается. Представим две версии. Первая печатает периметр и заканчивается. Вторая возвращает периметр, а отдельная команда выводит сохранённое значение. Снаружи обе могут показать одинаковое число, но их возможности для следующего вычисления различаются. Полезный вопрос при разборе ошибки звучит конкретно: что получила переменная после вызова? Добавление ещё нескольких сообщений в консоль может помочь наблюдать выполнение, однако само по себе не исправит отсутствующий возврат.
Попробуйте на практике
На бумаге сравните две вымышленные версии функции периметра.
- Запишите входные значения: ширина четыре, высота семь, ожидаемый периметр двадцать два.
- Для версии с выводом без явного возврата укажите отдельно видимый текст и возвращаемое значение.
- Для версии с возвратом сохраните результат в условную переменную и прибавьте к нему три.
- Объясните, какая часть программы должна отвечать за показ результата пользователю.
Как проверить результат. Разбор готов, если вы различаете число двадцать два на экране, число двадцать два в переменной и значение None. Дальнейшее вычисление должно использовать возвращённое число.
Частые вопросы
Можно ли в одной функции и печатать, и возвращать?
Да. Это два отдельных действия, и их можно сочетать осознанно. Важно понимать, какое значение получит вызывающий код независимо от сообщений в консоли.
Если return отсутствует, функция совсем ничего не делает?
Она может выполнять вычисления, вывод или другие действия. При нормальном завершении без явного возвращаемого значения результатом вызова будет None, что отличается от отсутствия выполнения.
Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.