На данном уроке мы рассмотрим функции, одну из фундаментальных основ программирования. Начнем!
Что такое функции в программировании?
Функции – это одна из основополагающих тем в программировании и важная часть практически любой программы.
Функции представляют собой специальный блок кода, который можно вызвать множество раз.
Чтобы создать функцию, нам нужно ключевое слово def, от англ. «define», что переводится, как «определять». То есть, мы как бы определяем функцию. Так же, как и с переменными, по названию функции мы должны понимать ее назначение.
Допустим, у нас функция, которая будет говорить «привет», поэтому мы назовем ее «say_hello». После ключевого слова пишем название функции и обязательно пишем круглые скобки, а затем двоеточие (Рис.1). Следующая строчка кода с отступом в четыре пробела будет относиться именно к этой функции. Пусть в этой строчке у нас будет «print(“Hello”)».
(Рис.1)
Итак, запустим нашу функцию. И увидим, что ничего не происходит (Рис.2). Но вопреки первым нашим возможным предположениям никакой ошибки нет.
(Рис.2)
Как и говорилось раннее, функцию можно вызывать множество раз. Но что же значит вызывать? Необходимо ввести в программе на любой нужной нам строчке имя функции, открыть и закрыть скобки и, запустив программу, мы как бы попросим функцию выполнить код, который у нее внутри. Таким образом, мы видим, что нам вывело «Hello» (Рис.3).
(Рис.3)
Давайте проверим, можем ли мы вызвать ее несколько раз (Рис.4). Да, действительно можем, и делать это можно неограниченное количество раз.
(Рис.4)
Виды функций
Рассмотренная выше функция – это самая простая функция, которую можно встретить - обычная. Но функции можно разделить на несколько видов: обычные, принимающие, возвращающие и анонимные.
Сегодня помимо обычных мы рассмотрим еще два вида функций. Сейчас разберемся, что такое принимающие функции. Принимающая – это та функция, в момент создания которой мы определяем какое-то значение, которое она будет принимать, а значит в момент вызова функции мы также должны будем его передать.
Рассмотрим на примере. Чтобы обозначить, что функция будет принимать значение, мы должны написать его в скобках после имени функции. Например, раз у нас функция приветствия, впишем «name», это будет нашим параметром. Он будет использоваться в коде, в теле функции (Рис.5). То есть после приветствия будет выводиться значение параметра «name».
(Рис.5)
Теперь, если дальше оставить все как есть и запустить программу, то мы увидим ошибку. Которая буквально гласит, что был пропущен один аргумент (Рис.6). Это действительно так, ведь в момент вызова функции мы не передавали никаких значений.
(Рис.6)
Поскольку функция принимающая (какое-то значение), у нее есть параметр, в момент вызова функции мы обязательно должны передать этот параметр ей. Попробуем вписать какие-то имена в каждую из выписанных нами функций (Рис.7). Запустим программу, при каждом вызове функции мы увидим разный ответ, сначала Денис, потом Макс и затем Антон.
(Рис.7)
Перейдем к возвращающей функции. Как можно понять по названию, возвращающая – это та функция, которая нам что-то возвращает. А возвращать что-то она будет с помощью команды return.
Допустим теперь у нас функция с лотереей, назовем ее «lottery», никаких значений она принимать не будет, то есть это самая обычная функция. В ней у нас будет переменная «tickets», которая будет списком с числами от 1 до 10 (Рис.8).
(Рис.8)
Суть функции в том, что будет происходить вычисление выигрышного билета и функция будет возвращать этот билет, его номер. Лотерея должна быть случайной, поэтому воспользуемся библиотекой random для выбора случайного значения из нашего списка.
Создадим переменную «win» и впишем команду choice из нашей библиотеки random, в скобках указываем наш список. Теперь пишем команду «return win», чтобы функция вернула нам выпавшее значение, то есть переменную «win»(Рис.9).
(Рис.9)
Давайте попробуем вызвать нашу функцию. В ответе ничего не видим (Рис.10). Но на самом деле возвращающие функции на месте своего вызова оставляют после себя какое-то значение. Мы можем поступить так, создать переменную и сохранить в нее вызов функции. А затем с помощью команды print вывести эту переменную (Рис.11). Видим ответ 8.
(Рис.10)
(Рис.11)
Если перезапустить программу, то ответ уже будет 6 (Рис.12), а если еще раз, то уже 4 (Рис.13), т. к. каждый раз случайным образом выбирается число из списка.
(Рис.12)
(Рис.13)
Стоит заметить, что команда return прекращает существование функции. Она работает по аналогии с командой break для циклов. После команды return функция прекращает выполнять дальнейшие команды.
Мы можем делать с функциями почти что угодно, например мы можем сложить два вызова функции между собой, т. к. по сути это целые числа и в ответе тоже видим целое число 14 (Рис.14). Поэтому мы можем выполнить с ними любую математическую операцию.
(Рис.14)
Принимающая и возвращающая функция
Существуют еще и одновременно принимающие и возвращающие функции. На самом деле в этом нет ничего сложного. Функции могут как принимать несколько параметров, так и возвращать.
Например, сделаем так, что наша функция будет еще и принимать значения, допустим «mon» и «thue», то есть понедельник и вторник. И напишем команду print, чтобы вывести эти значения. А также, дополним, что возвращать выигрышные билеты мы будем два раза, назовем переменные «win1» и «win2» (Рис.15).
(Рис.15)
Единственное, что нужно предусмотреть, это совпадение номеров. Поэтому пропишем, что после нахождения первого случайного элемента в списке, мы его удалим, то есть пропишем «tickets.remove(win1)». Таким образом в переменную «win2» такой же номер уже не попадет (Рис.16).
(Рис.16)
Теперь напишем, чтобы функция вернула нам оба значения «win1» и «win2». Для того чтобы корректно ее вызвать, нам нужно опять-таки создать две переменные и написать в них понедельник и вторник, а затем вывести их (Рис.17).
(Рис.17)
Таким образом в ответе мы видим, что условно в понедельник выигрышный билет был под номером 7, а во вторник 10. Можем запустить программу еще раз и увидим другие номера (Рис.18). А затем еще и т. д.
(Рис.18)
Если мы не знаем сколько параметров будет принимать функция, мы можем написать, например, «*args» для обычных параметров и «**kwargs» для именованных. Давайте попробуем вывести «*args». В целом это значит, что мы можем вписывать в скобки что угодно, например все тот же список от 1 до 10 (Рис.19).
(Рис.19)
Параметры по умолчанию
Помимо всего этого в принимающих функциях мы можем задавать значения по умолчанию. К примеру, у нас есть функция «test», которая по умолчанию будет принимать параметр «a», равный 2, и параметр «b», равный «True» (Рис.20). Соответственно, пишем, что будем выводить «a» и «b», а в момент вызова мы должны передать два параметра.
(Рис.20)
Но в случае с нашей функцией нам необязательно передавать параметры, если мы запустим программу, то увидим, что компьютер вывел «2» и «True» (Рис.21). Потому что тут были заданы параметры по умолчанию.
(Рис.21)
Но мы можем их переназначить. Например, в качестве первого параметра припишем «False», а в качестве второго «ok» (Рис.22).
(Рис.22)
Также мы можем распаковать в качестве параметров список или словарь. Рассмотрим на примере списка. Наша функция принимает два параметра. И у нас есть вызов функции, передадим сюда какой-нибудь список, а затем посмотрим, что произойдет (Рис.23).
(Рис.23)
В ответе мы видим наш список и все то же «True». То есть наш список встал на место параметра «а» и распаковался, как один объект. Чтобы распаковать его так, чтобы каждый элемент встал на соответствующее какому-то параметру место, нам нужно поставить звездочку перед списком (Рис.24).
(Рис.24)
Таким образом элемент списка «1» занял место параметра «а», а элемент списка «2» занял место параметра «b».
То же самое можно делать и со словарями, однако нужно понимать, что количество ключей должно совпадать с количеством параметров. А также желательно, чтобы названия ключей и параметров тоже совпадали. Для распаковки словаря нужно будет использовать две звездочки вместо одной.