Пример. Напишем функцию, которая определяет, являются ли три числа сторонами
треугольника. Функцию назовём is_triangle(a, b, c)
def is_triangle(a, b, c):
if a+b>c and b+c>a and c+a>b:
return True
else:
return False
Это решение правильное, но его можно упростить. Рассмотрим выражение внутри if
:
a+b>c and b+c>a and c+a>b
Значением этого выражения может быть либо True
, либо False
. Т.е. если,
например, мы присвоим это выражение переменной, то в ней будет лежать или True
,
или False
.
def is_triangle(a, b, c):
res = a+b>c and b+c>a and c+a>b
# в переменной res будет или True, или False
if res:
return True
else:
return False
Что мы сделали — значение выражения положили в переменную, внутрь if
положили
переменную. Это эквивалентное преобразование. Рассмотрим теперь условный оператор:
if res:
return True
else:
return False
Когда в переменной res
лежит True
, будет выполнена первая ветка if
, т.е.
выполнен оператор return True
.
Когда в переменной res
лежит False
, будет выполнена вторая ветка —
оператор return False
.
Всю вот эту конструкцию можно заменить эквивалентной:
return res
Действительно, когда в res
лежит True
, выполнится return True
, а когда
лежит False
— return False
.
Значит, функцию можно упростить таким образом:
def is_triangle(a, b, c):
res = a+b>c and b+c>a and c+a>b
# в переменной res будет или True, или False
return res
Переменная res
используется один раз в return
, значит её можно заменить
на выражение, ей присвоенное:
def is_triangle(a, b, c):
return a+b>c and b+c>a and c+a>b
print
и return
Ранее мы писали два вида функций: функции, которые печатали требуемые значения
при помощи print
, и функции, которые возвращали значения при помощи return
.
Пример. Функции hypot1(a, b)
и hypot2(a, b)
, которые вычисляют гипотенузу
прямоугольного треугольника:
def hypot1(a, b):
c = (a**2 + b**2)**0.5
print(с)
def hypot2(a, b):
c = (a**2 + b**2)**0.5
return c
Выглядят они похоже. Первая функция печатает значение при помощи вызова функции
print
, результат печатается в консоль. Вторая функция возвращает значение
при помощи оператора return
.
Если попытаемся их вызвать, то, на первый взгляд, отличий не увидим:
= RESTART: D:/temp/Коновалов/hypot.py
>>> hypot1(5, 12)
13.0
>>> hypot2(5, 12)
13.0
>>>
В обоих случаях на консоль напечаталось значение гипотенузы. Но механизм печати разный. Попробуем найти отличие.
>>> h1 = hypot1(5, 12)
13.0
>>> print(h1)
None
>>> h2 = hypot2(5, 12)
>>> print(h2)
13.0
>>>
Переменным h1
и h2
были присвоены значения, которые эти две функции возвращают.
Функция hypot1
явным образом ничего не возвращает, т.к. в ней отсутсвует оператор
return
. Если оператор return
отсуствует, то в конце функции неявно
подразумевается оператор return None
. Т.е. функция hypot1
неявно выглядит так:
def hypot1(a, b):
c = (a**2 + b**2)**0.5
print(c)
return None
Функция hypot1(a, b)
что делает:
c
.print(c)
, которая печатает значение c
в консоли.None
.Среда IDLE после вычисления выражения hypot1(5, 12)
видит, что результат
выражения — None
и его не печатает. Поэтому мы видим только результат печати
функции print
:
>>> hypot1(5, 12)
13.0
Вообще, среда IDLE в консоли никогда не печатает None
:
>>> None
>>> x = None
>>> x
>>>
Среда IDLE тут не распечатала None
ни когда мы его явно ввели, ни когда
мы попытались распечатать значение переменной x
. Другие значения в этих
случаях будут печататься:
>>> False
False
>>> y = False
>>> y
False
>>> 3.1415926
3.1415926
>>> pi = 3.1415926
>>> pi
3.1415926
>>>
Значения False
и 3.1415926
, в отличие от None
, печатаются как ожидалось.
Чтобы увидеть значение None
в консоли, нужно его распечатать функцией print
:
>>> print(None)
None
>>> print(x)
None
>>> print(h1)
None
>>>
Поэтому в примере выше мы писали не
>>> h1
а
>>> print(h1)
Соответственно, в примере
>>> h1 = hypot1(5, 12)
13.0
>>> print(h1)
None
мы видим, функция hypot1
напечатала значение, а возвращаемое значение
(т.е. результат вызова) — это None
, лежит в переменной h1
.
Функция hypot2(a, b)
возвращает величину гипотенузы как свой результат:
def hypot2(a, b):
c = (a**2 + b**2)**0.5
return c
При вызове в консоли hypot2(5, 12)
:
hypot2
вычисляет гипотенузу по теореме Пифагора, кладёт её
в переменную c
.c
как свой результат.13.0
, т.е. оно не равно None
,
и его печатает.>>> hypot2(5, 12)
13.0
>>> h2 = hypot2(5, 12)
>>> print(h2)
13.0
Во втором примере (с присваиванием) возвращаемое значение кладётся в переменную
h2
, а для присваиваний среда IDLE ничего не печатает. Вызов print(h2)
просто распечатывает значение переменной.
Заметим, что функция print(…)
тоже возвращает None
:
>>> p = print('hello')
hello
>>> print(p)
None
Ещё пример:
def example():
print("Это напечатает print")
return "Это вернёт return"
print("Это не напечатается")
============= RESTART: D:/temp/Коновалов/hypot.py ============
>>> example()
Это напечатает print
'Это вернёт return'
>>>
Здесь функция сначала напечатала первую строку, потом вернула вторую. Среда
IDLE увидела, что функция вернула не None
, и напечатала результат работы
функции (т.е. вторую строку). Возвращаемое значение печатается в машиночитаемой
форме, т.е. для строк — в кавычках.
Третья строчка не напечаталась, т.к. return
завершает выполнение функции.
Вызов print
— не завершает работу функции, это просто вызов другой функции.
Возвращаемое значение можно увидеть отдельно, если его присвоить переменной:
>>> z = example()
Это напечатает print
>>> z
'Это вернёт return'
>>>
Возвращаемое значение было присвоено переменной z
. В ответ на присваивание
сама среда IDLE ничего не печатает, мы видим только то, что печатает функция
при помощи print
.
Возвращённое значение можно использовать в вычислениях:
>>> 7 + hypot2(5, 12)
20.0
Напечатанное значение уже использовать нельзя, его можно только смотреть глазами:
>>> 7 + hypot1(5, 12)
13.0
Traceback (most recent call last):
File "<pyshell#70>", line 1, in <module>
7 + hypot1(5, 12)
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
>>>
Вызов функции hypot1
напечатал 13.0
, затем вернул None
. Мы попытались
сложить 7
(типа int
) и None
(типа NoneType
) и получили это сообщение
об ошибке: нельзя использовать +
для int
и NoneType
.