Возврат значений из функции. Оператор return
Функции могут передавать какие-либо данные из своих тел в основную ветку программы. Говорят, что функция возвращает значение. В большинстве языков программирования, в том числе Python, выход из функции и передача данных в то место, откуда она была вызвана, выполняется оператором return .
Если интерпретатор Питона, выполняя тело функции, встречает return , то он «забирает» значение, указанное после этой команды, и «уходит» из функции.
def cylinder(): r = float(input()) h = float(input()) # площадь боковой поверхности цилиндра: side = 2 * 3.14 * r * h # площадь одного основания цилиндра: circle = 3.14 * r**2 # полная площадь цилиндра: full = side + 2 * circle return full square = cylinder() print(square)
3 7 188.4
В данной программе в основную ветку из функции возвращается значение локальной переменной full . Не сама переменная, а ее значение, в данном случае – какое-либо число, полученное в результате вычисления площади цилиндра.
В основной ветке программы это значение присваивается глобальной переменной square . То есть выражение square = cylinder() выполняется так:
- Вызывается функция cylinder() .
- Из нее возвращается значение.
- Это значение присваивается переменной square .
Не обязательно присваивать результат переменной, его можно сразу вывести на экран:
. print(cylinder())
Здесь число, полученное из cylinder() , непосредственно передается функции print() . Если мы в программе просто напишем cylinder() , не присвоив полученные данные переменной или не передав их куда-либо дальше, то эти данные будут потеряны. Но синтаксической ошибки не будет.
В функции может быть несколько операторов return . Однако всегда выполняется только один из них. Тот, которого первым достигнет поток выполнения. Допустим, мы решили обработать исключение, возникающее на некорректный ввод. Пусть тогда в ветке except обработчика исключений происходит выход из функции без всяких вычислений и передачи значения:
def cylinder(): try: r = float(input()) h = float(input()) except ValueError: return side = 2 * 3.14 * r * h circle = 3.14 * r**2 full = side + 2 * circle return full print(cylinder())
Если попытаться вместо цифр ввести буквы, то сработает return , вложенный в except . Он завершит выполнение функции, так что все нижеследующие вычисления, в том числе return full , будут опущены. Пример выполнения:
r None
Но постойте! Что это за слово None , которое нам вернул «пустой» return ? Это ничего, такой объект – «ничто». Он принадлежит классу NoneType . До этого мы знали четыре типа данных, они же четыре класса: int , float , str , bool . Пришло время пятого.
Когда после return ничего не указывается, то по умолчанию считается, что там стоит объект None . При желании мы можете явно писать return None .
Более того. Ранее мы рассматривали функции, которые вроде бы не возвращали никакого значения, потому что в них не было оператора return . На самом деле возвращали, просто мы не обращали на него внимание, не присваивали никакой переменной и не выводили на экран. В Python всякая функция что-либо возвращает. Если в ней нет оператора return , то она возвращает None . То же самое, как если в ней имеется «пустой» return .
Возврат нескольких значений
В Питоне позволительно возвращать из функции несколько объектов, перечислив их через запятую после команды return :
def cylinder(): r = float(input()) h = float(input()) side = 2 * 3.14 * r * h circle = 3.14 * r ** 2 full = side + 2 * circle return side, full s_cyl, f_cyl = cylinder() print("Площадь боковой поверхности %.2f" % s_cyl) print("Полная площадь %.2f" % f_cyl)
Из функции cylinder() возвращаются два значения. Первое из них присваивается переменной s_cyl , второе – f_cyl . Возможность такого группового присвоения – особенность Python, обычно не характерная для других языков:
>>> a, b, c = 10, 15, 19 >>> a 10 >>> b 15 >>> c 19
Фокус здесь в том, что перечисление значений через запятую (например, 10, 15, 19 ) создает объект типа tuple . На русский переводится как «кортеж». Это разновидность структур данных, которые будут изучены позже.
Когда же кортеж присваивается сразу нескольким переменным, то происходит сопоставление его элементов соответствующим в очереди переменным. Это называется распаковкой.
Таким образом, когда из функции возвращается несколько значений, на самом деле из нее возвращается один объект класса tuple . Перед возвратом эти несколько значений упаковываются в кортеж. Если же после оператора return стоит только одна переменная или объект, то ее/его тип сохраняется как есть.
Распаковка не является обязательной. Будет работать и так:
… print(cylinder())
4 3 (75.36, 175.84)
На экран выводится кортеж, о чем говорят круглые скобки. Его также можно присвоить одной переменной, а потом вывести ее значение на экран.
Практическая работа
- Напишите программу, в которой вызывается функция, запрашивающая с ввода две строки и возвращающая в программу результат их конкатенации. Выведите результат на экран.
- Напишите функцию, которая считывает с клавиатуры числа и перемножает их до тех пор, пока не будет введен 0. Функция должна возвращать полученное произведение. Вызовите функцию и выведите на экран результат ее работы.
Примеры решения и дополнительные уроки в pdf-версии курса
X Скрыть Наверх
Python. Введение в программирование
Python-сообщество
![]()
- Начало
- » Центр помощи
- » Функция возвращает None
#1 Фев. 3, 2017 12:24:28
random_box Зарегистрирован: 2017-02-03 Сообщения: 4 Репутация: 0 Профиль Отправить e-mail
Функция возвращает None
Всем привет!
Есть задача написать функцию:
Функция принимает в качестве аргумента список строк.
Необходимо вернуть отсортированный список строк, в котором: сначала идет группа строк, начинающихся на ‘x’, затем все остальные.
Наример: из получится
Подсказка: это можно сделать при помощи склеивания 2х заранее отсортированных списков
words = ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] def front_x(words): x_files = [] for i in words: if i[0] == 'x': words.remove(i) x_files.append(i) return x_files.extend(words) print(front_x(words))
Вопрос: почему “return” возвращает “None”?
Смотрел работу кода в визуализаторе, все проходит нормально до строчки с “return”
Отредактировано random_box (Фев. 3, 2017 12:25:10)
#2 Фев. 3, 2017 13:15:36
FishHook От: Зарегистрирован: 2011-01-08 Сообщения: 8312 Репутация: 568 Профиль Отправить e-mail
Функция возвращает None
random_box
random_box
почему “return” возвращает “None”?
потому что list.extend возвращает None. Этот метод изменяет список. Существует такое хорошее правило: если метод что-то возвращает, он не должен вызывать побочных эффектов (то есть изменений чего-либо за пределами себя), и наоборот.
#3 Фев. 3, 2017 13:58:18
random_box Зарегистрирован: 2017-02-03 Сообщения: 4 Репутация: 0 Профиль Отправить e-mail
Функция возвращает None
FishHook

Я все понял! Огромное спасибо
#4 Фев. 3, 2017 17:16:08
marvellik Зарегистрирован: 2016-05-15 Сообщения: 639 Репутация: 73 Профиль Отправить e-mail
Функция возвращает None
def front_x(words, x_files = []): for i,x in enumerate(words): if x[0] == 'x': x_files.append(words.pop(i)) return sorted(x_files) + sorted(words) words = ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] print(front_x(words))
‘xanadu’, ‘xyz’, ‘aardvark’, ‘apple’, ‘mix’
Отредактировано marvellik (Фев. 3, 2017 17:16:41)
#5 Фев. 3, 2017 17:31:04
FishHook От: Зарегистрирован: 2011-01-08 Сообщения: 8312 Репутация: 568 Профиль Отправить e-mail
Функция возвращает None
def front_x(words, x_files = []):
Так нельзя делать никогда. Тот пустой список, который у вас в параметрах, создается один раз во время создания объекта функции. В нем будут сохраняться все изменения при каждом вызове функции.

Отредактировано FishHook (Фев. 3, 2017 17:31:20)
#6 Фев. 3, 2017 20:06:37
marvellik Зарегистрирован: 2016-05-15 Сообщения: 639 Репутация: 73 Профиль Отправить e-mail
Функция возвращает None
да согласен есть такой косяк что то написал под задачу но не учел что в реальности функция может быть вызвана много раз. но что так делать нельзя не согласен все зависит от требуемых результатов.
#7 Фев. 4, 2017 02:26:28
py.user.next От: Зарегистрирован: 2010-04-29 Сообщения: 9675 Репутация: 841 Профиль Отправить e-mail
Функция возвращает None
marvellik
но что так делать нельзя не согласен все зависит от требуемых результатов.
Побочный эффект это. Нужно писать функции так, чтобы было минимум побочных эффектов. А уж основывать что-то на побочном эффекте — верх беспомощности. Того же результата можно достичь с функцией без побочного эффекта.
Отредактировано py.user.next (Фев. 4, 2017 02:26:51)
#8 Фев. 4, 2017 07:33:17
FishHook От: Зарегистрирован: 2011-01-08 Сообщения: 8312 Репутация: 568 Профиль Отправить e-mail
Функция возвращает None
marvellik
не согласен все зависит от требуемых результатов
Если вы едите один и в темноте пишите свой маленький уютный проектик сам для себя, то вы вольны там делать что угодно. Но если вы пишите в команде или пишите на заказчика (что подразумевает, что ваш код когда-то может достаться на поддержку другому программисту) то отдавайте себе отчет, что если есть функция, то её в любой момент могут взять и заюзать без вашего ведома и вообще не так, как вы планировали. А теперь представьте себя на месте своего коллеги: вы вызываете кем-то ранее написаную функцию, получаете в ответе список. Используете этот список как планировали, но вдруг замечаете, что список получает изменения, которых вы туда не вносили. Как долго вы будете искать место возникновения побочки, и какими словами вы будете вспоминать своего коллегу?
Python: Возврат значений
В этом уроке подробнее разберем, как работать с созданными функциями, чтобы они были полезны.
Когда мы определяем функцию, она печатает на экран какие-то данные:
def greeting(): print('Hello, Hexlet!')
Пользы от таких функций немного, так как результатом нельзя воспользоваться внутри программы. Рассмотрим на примере.
Возьмем задачу обработки электронной почты. Когда пользователь регистрируется на сайте, то он может ввести email любым способом:
- Добавить случайно пробелы в начале или в конце: _support@hexlet.io__
- Использовать буквы в разном регистре: SUPPORT@hexlet.io
Если мы сохраним его в таком виде в базу данных, то пользователь не войдет на сайт. Чтобы этого не произошло, email нужно подготовить к записи в базу: привести его к нижнему регистру и обрезать пробелы по краям строки. Такая задача решается в пару строчек:
def save_email(): # Email приходит из формы email = ' SuppORT@hexlet.IO' # Обрезаем пробельные символы trimmed_email = email.strip() prepared_email = trimmed_email.lower() print(prepared_email) # Здесь будет запись в базу данных
Этот код стал возможен благодаря тому, что значение вернулось. Методы strip() и lower() ничего не печатают на экран, они возвращают результат своей работы. Поэтому мы можем записать его в переменные. Если бы они печатали на экран, мы бы не могли присвоить результат переменной. Например, так мы не можем сделать с функцией greeting() :
message = greeting() # в действительности, функция print() возвращает None # None — специальный объект, используемый для представления отсутствия значения print(message) # => None
Теперь изменим функцию greeting() так, чтобы она возвращала данные. Для этого выполним возврат вместо печати на экран:
def greeting(): return 'Hello, Hexlet!'
return — это инструкция. Она берет записанное справа выражение и отдает его тому коду, который вызвал метод. Здесь выполнение функции завершается.
# Теперь мы можем использовать результат работы функции message = greeting() print(message) # => Hello, Hexlet! # И даже выполнить какие-то действия над результатом print(message.upper()) # => HELLO, HEXLET!
Любой код после return не выполняется:
def greeting_with_code_after_return(): return 'Hello, Hexlet!' print('Я никогда не выполнюсь')
Даже если функция возвращает данные, это не ограничивает ее в том, что она печатает. Кроме возврата данных мы можем и печатать:
def greeting_with_return_and_printing(): print('Я появлюсь в консоли') return 'Hello, Hexlet!' # И напечатает текст на экран, и вернет значение message = greeting_with_return_and_printing()
Возвращать можно не только конкретное значение. Так как return работает с выражениями, то справа от него может быть что угодно. Здесь нужно руководствоваться принципами читаемости кода:
def greeting(): message = 'Hello, Hexlet!' return message
Здесь мы не возвращаем переменную. Возвращается всегда значение, которое находится в этой переменной. Ниже пример с вычислениями:
def double_five(): # или return 5 + 5 result = 5 + 5 return result
Определить функцию мало. Еще важно, чтобы она была полезна, и результатом можно было воспользоваться. А теперь подумайте, что вернет вызов, определенной ниже функции run() ?
# Определение def run(): return 5 return 10 # Что будет выведено на экран? print(run())
Задание
Реализуйте функцию say_hurray_three_times() , которая возвращает строку ‘hurray! hurray! hurray!’.
hurray = say_hurray_three_times() print(hurray) # => hurray! hurray! hurray!
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Почему функция возвращает None?
Доброго времени суток. Решил начать самообучаться азам Python. Сейчас играюсь с функциями и return. Написал вот такой калькулятор, но он возвращает None, хотя весь код исполняется.
Подскажите, пожалуйста, в чем я ошибаюсь. Самостоятельный поиск в гугле не помог.
#Вычисляем факториал def factorial(num1): if num1 == 1: return 1 elif num1 > 0: return num1 * factorial (num1 - 1) else: return ('Не верное число') #Вычисляем сумму def summa(num1, num2): return (num1 + num2) #Вычисляем разность def raznost(num1, num2): return (num1 - num2) #Вычисляем произведение def proisvedenie(num1, num2): return (num1 * num2) #Вычисляем деление def delenie(num1, num2): if num2 == 0: return ('Делить на 0 нельзя') else: return (num1 / num2) #Определяем что делать def deistvie(znak, num1, num2): if znak == '!': factorial(num1) elif znak == '+': summa(num1, num2) elif znak == '-': raznost(num1, num2) elif znak == '*': proisvedenie(num1, num2) elif znak == '/': delenie(num1, num2) else: return ('Нет такого действия') #Получаем данные def inputs(): num1 = float(input('Введите число: ')) znak = input('Введите знак (+, -, *, /, !): ') if znak == '!': num2 = '' else: num2 = float(input('Введите второе число: ')) deistvie (znak, num1, num2) print (inputs())
- Вопрос задан более трёх лет назад
- 6874 просмотра
Комментировать
Решения вопроса 1
В вашей функции deistvie происходит просто вызов функций сложение, вычитания, умножения и т.д. И вы с ними ничего не делатете, т.е. как вариант, это выводить результат, например так:
#Определяем что делать def deistvie(znak, num1, num2): if znak == '!': print(factorial(num1)) elif znak == '+': print(summa(num1, num2)) elif znak == '-': print(raznost(num1, num2)) elif znak == '*': print(proisvedenie(num1, num2)) elif znak == '/': print(delenie(num1, num2)) else: return ('Нет такого действия')
либо надо возвращать значения в deistvie и в inputs, т.е. таким образом
#Определяем что делать def deistvie(znak, num1, num2): if znak == '!': return factorial(num1) elif znak == '+': return summa(num1, num2) elif znak == '-': return raznost(num1, num2) elif znak == '*': return proisvedenie(num1, num2) elif znak == '/': return delenie(num1, num2) else: return ('Нет такого действия') #Получаем данные def inputs(): num1 = float(input('Введите число: ')) znak = input('Введите знак (+, -, *, /, !): ') if znak == '!': num2 = '' else: num2 = float(input('Введите второе число: ')) return deistvie (znak, num1, num2)