Функции в Python: введение и объект None
Обновлено:
1. Новая большая тема — функции
Следующая большая тема посвящена созданию собственных функций.
Для определения функции в Python используется ключевое слово:
def
Ключевое слово def, параметры, тело функции и вызов собственных функций будут рассматриваться в следующей части.
На этом уроке мы сначала подготовимся к теме и разберём:
- объект
None; - возвращаемое значение функции;
- функции, которые возвращают
None; - основное назначение функций;
- устранение дублирования кода.
2. Объект None
В Python существует специальный объект:
None
None обозначает отсутствие значения.
Можно сказать:
В этом месте сейчас нет полезного значения.
None — это не строка, поэтому кавычки не используются.
Правильно:
None
Неправильно:
'None'
Вторая запись является обычной строкой из четырёх символов.
3. None — это полноценный объект
None является полноценным объектом Python.
Его можно сохранить в переменную:
result = None
Теперь имя result ссылается на объект None:
result ─────> None
Правильнее говорить не «пустая переменная», а:
Переменная
resultссылается наNone.
Или:
В переменной
resultпока отсутствует полезное значение.
4. В Python существует только один объект None
None является единственным объектом своего типа.
Разные переменные, которым присвоен None, ссылаются на один объект:
first_result = None
second_result = None
Упрощённая схема:
first_result ──┐
├────> None
second_result ─┘
В официальной документации None описывается как единственный объект, обозначающий отсутствие значения.
5. None является неизменяемым объектом
Состояние объекта None изменить нельзя.
Нельзя добавить в него число, изменить его содержимое или превратить сам объект None в строку.
Если мы перезапишем переменную:
result = None
result = 25
объект None не изменится.
Имя result просто начнёт ссылаться на другой объект:
Сначала:
result ─────> None
После перезаписи:
result ─────> 25
6. None является встроенной константой
Имя None заранее существует во встроенной области видимости Python.
Его не нужно создавать или импортировать.
Мы можем сразу использовать его:
result = None
Имя None нельзя использовать для своей переменной и нельзя перезаписать. Попытка присваивания приведёт к синтаксической ошибке.
Неправильно:
None = 10
Будет ошибка:
SyntaxError
7. Размер объекта None
Иногда можно встретить утверждение:
Объект
Noneвсегда занимает 16 байт.
Так говорить неправильно.
Размер объекта зависит от:
- реализации Python;
- версии Python;
- разрядности системы;
- особенностей сборки интерпретатора.
В некоторых версиях 64-битного CPython результат действительно может быть равен 16 байтам, но это не универсальная гарантия языка.
На данном этапе точный размер объекта None запоминать не нужно.
Главное понимать:
None— небольшой служебный объект;- он существует в единственном экземпляре;
- разные переменные могут ссылаться на один объект
None.
8. Обращение к None в IDLE
В IDLE выполним:
None
Визуально ничего не появится.
Создадим переменную:
result = None
Затем обратимся к ней:
result
IDLE снова ничего не выведет.
Это не означает, что переменная не существует или что в ней ничего нет.
В ней находится объект None.
9. Почему IDLE не показывает None
Интерактивная оболочка IDLE обычно отображает результат введённого выражения.
Например:
10
IDLE покажет:
10
Если ввести:
'Hello'
IDLE покажет:
'Hello'
Но отображение результата None специально подавляется.
Интерактивный механизм Python проверяет результат выражения и ничего не печатает, если результатом является None.
Поэтому None не невидим вообще. Он просто автоматически не отображается как результат выражения в интерактивной оболочке.
10. Как увидеть None
Чтобы явно вывести объект None, используем функцию print():
print(None)
Результат:
None
Пример с переменной:
result = None
print(result)
Результат:
None
Функция print() явно преобразует переданный объект в текстовое представление и выводит его.
11. Для чего используется None
None часто используется как первоначальное значение, когда полезный результат пока неизвестен.
Например:
user_name = None
Это может означать:
Имя пользователя пока не получено.
Другой пример:
discount = None
Это может означать:
Пока неизвестно, будет ли назначена скидка.
Ещё пример:
order_result = None
Это может означать:
Заказ ещё не обработан, поэтому результата пока нет.
12. None как временное значение
Предположим, программа позже должна получить цену товара.
В начале работы цена ещё неизвестна:
product_price = None
Позже нужное значение поступило:
product_price = 1500
Имя product_price начало ссылаться на число:
Сначала:
product_price ─────> None
Позже:
product_price ─────> 1500
Если значение так и не поступило, в переменной останется None.
В будущем мы научимся проверять это с помощью условных конструкций.
13. None не является нулём
None не означает число 0.
number = 0
В переменной находится настоящее целое число.
number = None
В переменной отсутствует числовое значение.
Это разные ситуации.
Например:
- нулевой баланс — это
0; - баланс пока неизвестен — это
None.
14. None не является пустой строкой
Пустая строка:
''
является экземпляром класса str.
Она существует и содержит ноль символов.
None:
None
обозначает отсутствие строкового значения.
Например:
- пользователь оставил пустой текст —
''; - текст от пользователя ещё не получен —
None.
15. None не является пустым списком
Пустой список:
[]
является настоящим списком без элементов.
None означает, что списка пока нет.
Например:
orders = []
может означать:
Список заказов получен, но заказов нет.
А:
orders = None
может означать:
Список заказов ещё не был получен.
16. Функции возвращают значения
Мы уже использовали функции, которые возвращают полезный результат.
Например:
result = len('Hello')
Функция len() возвращает:
5
Поэтому в переменную result записывается число:
result = 5
17. Результат функции sum()
numbers = [10, 20, 30]
result = sum(numbers)
Функция sum() возвращает сумму:
60
Теперь:
print(result)
выведет:
60
Упрощённо выполнение можно представить так:
sum(numbers) ─────> 60
18. Другие возвращаемые значения
Функция abs() возвращает модуль числа:
result = abs(-10)
В переменной находится:
10
Функция max() возвращает максимальный элемент:
result = max([10, 25, 5])
В переменной находится:
25
Функция round() возвращает округлённое значение:
result = round(3.8)
В переменной находится:
4
19. Не каждая функция возвращает полезный результат
Некоторые функции выполняют действие, но не создают полезного результата для дальнейших вычислений.
Например, основная задача функции print():
Вывести информацию на экран.
Функция выполняет эту задачу, но результат печати не нужно возвращать в программу.
Поэтому print() возвращает:
None
20. Что возвращает print()
Рассмотрим код:
result = print('Hello')
Сначала функция выполняет своё основное действие:
Hello
После этого функция возвращает:
None
Именно None записывается в переменную result.
Проверим:
print(result)
Результат:
None
21. Полный пример с print()
result = print('Hello')
print(result)
Результат:
Hello
None
Первая строка появилась потому, что сработала функция:
print('Hello')
Вторая строка появилась потому, что мы отдельно распечатали значение переменной:
print(result)
В переменной result находился объект None.
22. Вывод на экран и возвращаемое значение — не одно и то же
Очень важно различать два действия.
Вывод на экран
print('Hello')
Функция показала текст пользователю.
Возвращаемое значение
result = print('Hello')
После выполнения функции в переменную result записался объект:
None
Текст:
Hello
не записался в переменную result.
Он был только выведен на экран.
23. Пример с задержкой
Для наглядности можно использовать функцию sleep() из модуля time.
from time import sleep
result = print('Hello')
sleep(2)
print(result)
Результат работы:
Hello
После этого программа подождёт примерно две секунды и выведет:
None
Функция sleep() приостанавливает выполнение программы на указанное количество секунд.
24. Порядок выполнения примера
from time import sleep
result = print('Hello')
sleep(2)
print(result)
Python выполняет код сверху вниз.
Сначала:
print('Hello')
выводит:
Hello
Затем возвращает None, который сохраняется в result.
После этого:
sleep(2)
приостанавливает выполнение.
В конце:
print(result)
выводит:
None
25. Функция sleep() тоже возвращает None
Результат sleep() также можно сохранить:
from time import sleep
sleep_result = sleep(2)
print(sleep_result)
Программа подождёт примерно две секунды, после чего выведет:
None
Основная задача sleep() — приостановить выполнение программы.
Она не должна вычислять и возвращать полезное число или строку.
26. Функция должна что-то вернуть
В Python результатом вызова функции всегда становится определённый объект.
Если функция не возвращает полезный результат, результатом является:
None
Собственные функции без явно возвращённого значения тоже будут возвращать None. Подробно это будет рассмотрено после изучения ключевого слова def и возврата результатов.
27. Функции с полезным результатом
Примеры функций, которые возвращают объект для дальнейшей работы:
len('Hello')
возвращает:
5
sum([10, 20, 30])
возвращает:
60
max([10, 20, 30])
возвращает:
30
abs(-10)
возвращает:
10
28. Функции с основным действием
Примеры функций, основная задача которых состоит не в вычислении полезного результата:
print('Hello')
Основное действие — вывод текста.
sleep(2)
Основное действие — пауза в выполнении программы.
После выполнения такие функции возвращают:
None
29. Подсказки Visual Studio Code
Если навести указатель на имя функции в Visual Studio Code, редактор может показать краткую информацию о ней.
Для функции, возвращающей None, в подсказке часто можно увидеть запись:
-> None
Например, такая подсказка означает:
После выполнения функция возвращает объект
None.
Точный вид подсказки зависит от установленного расширения, версии Python и настроек редактора.
30. Зачем нужны функции
Функция позволяет один раз описать определённое действие или алгоритм, а затем использовать его много раз.
Например, функция:
sum()
уже содержит алгоритм сложения элементов итерируемого объекта.
Мы можем передать ей разные списки:
first_numbers = [10, 20, 30]
second_numbers = [5, 15, 25]
third_numbers = [100, 200, 300]
И использовать один и тот же готовый алгоритм:
print(sum(first_numbers))
print(sum(second_numbers))
print(sum(third_numbers))
31. Результат примера с sum()
first_numbers = [10, 20, 30]
second_numbers = [5, 15, 25]
third_numbers = [100, 200, 300]
print(sum(first_numbers))
print(sum(second_numbers))
print(sum(third_numbers))
Результат:
60
45
600
Мы использовали один алгоритм три раза.
Нам не пришлось самостоятельно заново описывать сложение элементов каждого списка.
32. Дублирование кода
Дублирование кода — это повторение одинаковых или почти одинаковых участков программы.
Предположим, в программе нужно много раз рассчитывать сумму чисел.
Без готовой функции пришлось бы каждый раз повторять алгоритм:
получить первый элемент;
получить второй элемент;
сложить значения;
получить следующий элемент;
снова сложить;
продолжать до конца объекта.
Если подобных мест много, программа становится:
- длиннее;
- сложнее;
- менее понятной;
- труднее для исправления;
- труднее для проверки.
33. Функция избавляет от дублирования
Вместо повторения алгоритма мы вызываем:
sum(numbers)
Название функции сразу показывает, что программа делает:
Вычисляет сумму элементов.
Функция позволяет скрыть сложный алгоритм за коротким и понятным именем.
34. Пример с интернет-магазином
Предположим, интернет-магазин хранит суммы заказов за разные дни:
monday_orders = [1200, 800, 1500]
tuesday_orders = [900, 2100, 500]
wednesday_orders = [1700, 600, 1100]
Общую сумму за каждый день можно получить так:
monday_total = sum(monday_orders)
tuesday_total = sum(tuesday_orders)
wednesday_total = sum(wednesday_orders)
Мы используем одну функцию для разных данных.
35. Пример со складом
Предположим, на разных складах хранится разное количество товаров:
first_warehouse = [10, 20, 30]
second_warehouse = [5, 15, 25]
third_warehouse = [100, 50, 75]
Количество товаров:
first_total = sum(first_warehouse)
second_total = sum(second_warehouse)
third_total = sum(third_warehouse)
Не нужно создавать отдельный алгоритм для каждого склада.
36. Функции делают код короче
Сравним длинное описание:
Возьми каждый элемент списка.
Последовательно сложи все элементы.
Сохрани итоговый результат.
И короткий вызов:
sum(numbers)
Функция делает код компактнее, но при этом не скрывает его смысл.
По названию sum понятно, что вычисляется сумма.
37. Функции делают код понятнее
Хорошее имя функции сообщает, какую задачу она выполняет.
Например:
len(text)
означает получение длины.
max(numbers)
означает поиск максимального значения.
round(price, 2)
означает округление числа.
В будущем мы будем придумывать понятные имена собственным функциям.
38. Функции упрощают исправление кода
Предположим, один алгоритм был скопирован в десять мест программы.
Если в нём обнаружится ошибка, придётся:
- найти все десять копий;
- исправить каждую;
- убедиться, что одна копия не была пропущена.
Если алгоритм находится внутри одной функции, исправляется только сама функция.
Все места, где она вызывается, начнут использовать исправленный вариант.
39. Функции упрощают проверку программы
Небольшую функцию легче проверить отдельно от всей программы.
Например, можно передать ей несколько разных наборов данных и убедиться, что она возвращает правильные результаты.
В дальнейшем мы познакомимся с тестированием функций.
40. Функции разделяют большую программу на части
Большая программа может состоять из множества небольших задач.
Например, программа интернет-магазина должна:
- рассчитать стоимость заказа;
- определить скидку;
- сформировать сообщение;
- сохранить заказ;
- отправить уведомление.
Вместо одного огромного участка кода для каждой задачи можно создать отдельную функцию.
Так программу проще читать и развивать.
41. Функции можно переиспользовать
Одну функцию можно вызвать:
- несколько раз в одном файле;
- из разных частей программы;
- в других файлах;
- в других проектах.
Ранее мы уже видели пример импорта:
from math import prod
Функция prod() была написана разработчиками Python, а мы получили возможность использовать готовый код в своей программе.
42. Функции позволяют использовать чужие алгоритмы
Когда мы вызываем:
sum(numbers)
нам не нужно знать все внутренние детали работы sum().
Нам достаточно знать:
- что передать;
- что функция сделает;
- какой результат она вернёт.
Такая возможность позволяет создавать программы из уже готовых строительных блоков.
43. Функция получает данные и возвращает результат
Упрощённую работу функции можно представить так:
Данные → функция → результат
Например:
[10, 20, 30] → sum() → 60
'Hello' → len() → 5
-10 → abs() → 10
Но иногда результатом является None:
'Hello' → print() → None
При этом функция print() дополнительно выводит текст на экран.
44. Возвращаемое значение можно сохранить
numbers = [10, 20, 30]
total = sum(numbers)
Функция вернула число:
60
Имя total стало ссылаться на этот результат.
После этого результат можно использовать дальше:
rounded_total = round(total)
45. None тоже можно сохранить
result = print('Hello')
Функция вернула:
None
Поэтому переменная result существует и ссылается на полноценный объект.
Просто этот объект сообщает:
Полезного результата нет.
46. Почему функция print() возвращает None
Основная задача print() уже выполнена:
Информация выведена на экран.
Возвращать напечатанный объект обычно не нужно.
Если написать:
result = print('Hello')
функция не возвращает строку 'Hello'.
Она возвращает отсутствие полезного результата:
None
47. Главные преимущества функций
Функции позволяют:
- не повторять одинаковый код;
- давать алгоритмам понятные имена;
- уменьшать размер программы;
- делить большую программу на части;
- повторно использовать готовый код;
- исправлять алгоритм в одном месте;
- отдельно проверять разные части программы;
- скрывать сложную внутреннюю реализацию.
48. Что пока не изучаем
На этом уроке мы не рассматриваем:
- синтаксис определения собственной функции;
- параметры;
- аргументы собственных функций;
- именованные аргументы;
- значения по умолчанию;
- ключевое слово
return; - локальные переменные функции;
- рекурсию;
- декораторы.
Эти темы будут изучаться постепенно.
Сейчас важно подготовить основу:
- понимать объект
None; - отличать вывод от возвращаемого значения;
- понимать, что функция может вернуть
None; - понимать, зачем программа делится на функции.
49. Основные правила урока
None обозначает отсутствие значения:
result = None
None является единственным неизменяемым объектом своего типа.
В IDLE результат None автоматически не отображается:
result
Чтобы увидеть его явно:
print(result)
Функции могут возвращать полезные значения:
result = sum([10, 20, 30])
Результат:
60
Функция print() выполняет вывод, но возвращает:
None
Пример:
result = print('Hello')
print(result)
Результат:
Hello
None
Главное назначение функций:
Один раз описать алгоритм и использовать его многократно, не дублируя код.
В следующей части мы начнём создавать собственные функции с помощью ключевого слова:
def