Пример. Напишем функцию, которая определяет, являются ли три числа сторонами
треугольника. Функцию назовём 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.