Что такое аргумент функции в python
Перейти к содержимому

Что такое аргумент функции в python

  • автор:

# Функции

Функция — блок кода для выполнения определенной задачи, который можно использовать многократно в разных частях программы. Существует множество встроенных в Python готовых функций. Некоторые вы уже применяли ранее: print() , str() , int() , float() , len() .

Создание функции называется определение. Оно начинается с ключевого слова def (от англ. definition, «определение»), затем идут имя функции, её аргументы, или параметры в круглых скобках и двоеточие. Начиная со следующей строки, с отступом в 4 пробела от начала, записывают тело функции — код, который она выполняет. Обращение к функции называется вызов функции. Функция вызывается по имени, при вызове ей передают аргументы, с которыми она должна что-то сделать.

Напишем приветствие как функцию:

Создали функцию с именем say_hello (англ. say hello, "поздороваться"). В любом месте программы при вызове say_hello() будет выводиться на экран приветствие с текстом, зависящим от аргумента current_hour (англ. current hour , "текущий час").

# Упражнения

  1. На основе заготовленного кода напишите функцию print_friends_count() для вывода количества друзей. Аргументом сделайте friends_count . Вызовите эту функцию не менее трёх раз с разными аргументами. Значениями friends_count могут быть любые натуральные числа.
  1. Напишите цикл для запусков print_friends_count() c аргументами от 1 до 10. Проследите изменения выведенных надписей.

# Упражнения tkinter

Напишите оконное приложение выводящее список количества друзей.

Напишите оконное приложение с полем ввода количества друзей. Кнопкой при нажатии на которую выводится сообщение о количестве друзей.

# Аргументы функции

В Python аргументам функций может быть присвоено значение по умолчанию. Оно подставляется, когда при вызове функции вы не оставляете насчёт аргументов никаких инструкций.

Функция say_hello() принимает два аргумента — current_hour и name (англ. name, "имя"), которому задано значение по умолчанию. При вызове только с одним аргументом current_hour значением второго аргумента name станет пустая строка.

При вызове функции можно явно указывать, какому аргументу какое значение соответствует. В таком случае порядок следования аргументов в скобках роли не играет.

# Упражнения

Допишите код функции print_friends_count() , добавьте аргумент name со значением по умолчанию. Если вы при вызове передаёте функции имя, она должна вывести на экран строку вида '<имя>, у тебя N друзей' , если нет — тогда просто 'У тебя N друзей' .

Анфиса может анализировать списки. Например, подсчитывать дни, когда в вашем городе или в городах ваших друзей стояла хорошая погода.

Есть списки средних дневных температур в Москве за май 2017 и 2018 годов. Создайте функцию comfort_count(temperatures) для подсчёта в переданном списке комфортных дней — дней с температурой воздуха от 22 до 26 градусов включительно.

Функция в результате работы должна вывести на экран строку 'Количество комфортных дней в этом месяце: N' , где N — результат подсчёта в цикле с условием. Сначала посчитайте приятные дни в мае 2017-го года, а потом — в мае 2018-го.

# Разбиение на функции

В больших проектах, написанных на Python, принято выносить весь повторяющийся код в отдельные функции перед телом основной программы. Посмотрим на пример:

Функция say_hello() содержит основную логику, а runner() (от англ. run, "запускать") выполняет роль управляющего механизма. Такое разделение придаёт коду программы аккуратный внешний вид, делает его более выразительным, упрощает чтение.

# Упражнения

  1. Подготовьте код Виты к использованию на сервере.
  • Напишите функцию process_query() (англ. process query, «обработать запрос»). Перенесите в неё весь код из тела основной программы. Эта функция будет принимать на вход запросы пользователя и выдавать ответ на них. Пока она может обработать всего один запрос — сообщить количество друзей.
  • Добавьте вызов функции process_query() в тело основной программы.
  1. На серверы приходит множество запросов — от разных пользователей или от других серверов. Измените функцию process_query() (обработчик запроса), чтобы она поддерживала несколько разных запросов, а не только один.
  • Добавьте аргумент query в функцию process_query() . Этот аргумент будет сообщать, какой именно запрос необходимо обработать.
  • В начало функции process_query() добавьте проверку значения переменной query: если значение равно 'Сколько у меня друзей?' — выведите ответ на этот вопрос, как в предыдущем задании;
  • в противном случае — выведите '<неизвестный запрос>'. Добавьте вызов process_query('Сколько у меня друзей?') в основное тело программы. Добавьте ещё один вызов process_query('Как меня зовут?') в основное тело программы.
  1. Доработайте программу.
  • Добавьте в функцию process_query() обработку ещё одного запроса 'Кто все мои друзья?'. В ответ нужно выводить на экран Твои друзья: <список_друзей>, где <список_друзей>— строка, состоящая из списка друзей, разделённых запятой и пробелом.
  • Добавьте вызов process_query('Кто все мои друзья?') в тело основной программы.

# Возврат значений из функции

Пока что все наши функции печатали результаты своей работы на экран. Но обычно задача функции не сводится к выступлениям в печати. Как правило, это код, производящий специальные вычисления. Он не выводит результаты на экран, а возвращает их как значения. Значение вернётся в вызывающий код, и там будет использовано. Например, сохранено в переменной. Если программе нужно, к примеру, несколько раз посчитать одно и то же, эти вычисления поручают особым функциям:

Ключевое слово return (англ. «возвращать») указывает, какое значение функция вернёт основному коду.

# Упражнения

  1. Доработаем программу подсчёта комфортных дней в мае.
  • Измените функцию comfort_count() , чтобы она не печатала количество комфортных дней, а возвращала.
  • Чтобы увидеть результат выполнения функции, напечатайте его в основном коде командой print(comfort_count(may_2017)) .

# Вызов функции из функции

Функцию можно вызвать не только из основного кода, но и из другой функции.

Хорошая привычка — выделять вычисления и вывод в отдельные функции, чтобы печать результатов не была разбросана по всему коду.

Если бы мы ошиблись и забыли вернуть строку text из функции show_info(), то вывод получился бы странный:

Что такое None здесь? Это специальное значение в Python, и оно обозначает. ничего (англ. none, "ничто"). Если значение какой-нибудь переменной равно None , обычно это значит, что она не определена, не имеет никакого значения. Функция runner() печатает результаты вызовов функции show_info() . Так как в ней нет return , то она ничего не возвращает, и print() печатает это самое ничего.

Функции#

Про определение функций в python можно подробно прочитать в документации по ссылке.

Объявление функции ( function definition ) состоит из заголовка и тела.

Заголовок начинается с ключевого слова def , за которым должно следовать название (имя) функции и список формальных параметров. Завершается заголовок символом двоеточия.

Далее приводится тело функции, инструкции в котором приводятся с постоянным отступом вправо относительно заголовка функции.

Первой строкой в теле функции допускается указывать документирующую строку.

Когда интерпретатор встречает определение функции, он создаёт вызываемый объект-функцию и связывает этот объект с указанным при объявлении именем. Это имя также функции сохраняется в атрибут __name__ объекта-функции.

В ячейке выше на первой строке мы объявили функцию с именем add принимающую два аргумента под именами x и y .

На следующей строке располагается документирующая строка.

Документирующая строка сохраняется в атрибут __doc__ объекта функции и также выводится в справке по функции, которую можно сгенерировать встроенной функцией help.

На последней строке функция возвращает результат вычисления выражения x + y вызывающему коду.

Управление потоком управления и возвращение значений из функции#

При вызове функции поток управления программой передаётся этой функции. Поток управления программой возвращается обратно вызывающему коду, когда исполнение функций завершается, что может произойти по трём причинам:

встречено ключевое слово return ;

достигнут конец функции;

возникло необработанное исключение, которое начало распространяться по стеку вызовов.

Последний случай разбирается позднее в разделе “ Исключения ”, разберем первые два.

Если встречается конструкция вида

т.е. ключевое слово return и некоторое выражение expression , то вызывающему коду возвращается результат вычисления expression . Именно такая ситуация и встречается в определенной выше функции add : в качестве expression выступает выражение x + y .

Если же после ключевого слова return ничего не стоит, т.е. встречается конструкция вида

то вызывающему коду возвращается значение None .

Если же функция заканчивается без ключевого слова return , то после исполнения последней инструкции тела функции вызывающему коду возвращается значение None . Т.е. следующие три определения функции эквиваленты.

Таким образом функция всегда возвращает какое-то значение, если её исполнение завершилось без возникновения исключений. Это значение явно задаётся выражением справа от ключевого слова return или возвращается None , если ключевое слово return не встретилось при исполнении тела функции или справа от оператора return ничего не указано.

Функции как объекты первого класса#

Прочитав объявление функции, интерпретатор создаёт вызываемый объект-функцию типа function и связывает его с указанным при объявлении функции именем. При этом объекты функционального типа function ничем не выделяются на фоне объектов всех остальных типов. Как и с любыми другими объектами в python можно совершать следующие операции и над функциями:

передать в качестве аргумента функции;

возвращать из функции;

В программировании такие объекты с такими свойствами принято называть объектами первого класса и далеко не во всех языках программирования функции являются таковыми. Но в python это так и давайте продемонстрируем это.

Присваивание переменной#

Присвоение переменной в python — связывание с именем. В качестве демонстрации этой возможности свяжем встроенную функцию print с именем p и вызовем её от этого имени.

Передача в качестве аргумента функции#

Передачу функции в качестве аргумента другой функции мы уже встречали на примере получения справки функцией help . Разберем пример того, как пользовательская функция может принимать в качестве параметра объект-функцию.

В ячейке выше определена примитивная функция print_function_name , которая просто печатает содержимое атрибута __name__ функции. Далее на вход этой функции сначала передаётся определенная ранее функция add . А потом на вход этой функции передаётся она сама! Да, python настолько гибкий, что функция может обработать саму себя. Правда сложно представить себе ситуацию, где такая возможность пригодится и будет лучшей из всех возможных альтернатив.

Напишем чуть более содержательную функцию apply , которая принимает на вход функцию f и список l и подменяет каждый элемент l[i] значением f(l[i]) , т.к. применяет функцию f к элементам списка l на месте.

На самом деле есть встроенная функция map, которая делает то же самое, только не на месте.

Возвращение из функции. Замыкание#

Функция может возвращать функцию из себя. Распространенное применение такого приема — декораторы (см. “ Декораторы ”). Одна из основных причин такой распространенности — возможность реализовать шаблон замыкание ( closure ).

Рассмотрим самый простой пример. Реализуем функцию, которая генерирует функцию, запоминающую момент своего создания.

Разберем, как этот пример работает. Обратим внимание на функцию make_remembering_function .

Для начала обратим внимание на то, что внутри тела этой функции объявляется другая функция remembering_function и она же возвращается в качестве результата. При каждом вызове функции make_remembering_function интерпретатор заново встречает объявление функции remembering_function , создаёт функциональный объект и связывает его с именем remembering_function в пространстве локальных имен функции make_remembering_function (каждому вызову одной и той же функции соответствует своё уникальное пространство локальных имен).

Теперь обратим внимание, что созданная функция remembering_function обращается к переменной time_of_creation , которая в этой функции не объявляется.

Такие переменные считаются свободными переменными и к списку таковых даже можно получить доступ напрямую.

Связывание свободных переменных с объектов происходит во время вызова функции. Поиск происходит в приоритете

nonlocals — пространство локальных имен замыкающей функции (в данному примере пространство локальных имен функции make_remembering_function );

globals — глобальное пространство имен модуля, в котором объявлена эта функция;

builtins — пространство встроенных имен.

Искусственно произвести процесс разрешения можно средствами модуля inspect, который предназначен для инспекции python объектов. Метод inspect.getclosurevars разрешает все имена, которые используются в функции, но не объявлены в самой функции, с объектами.

В данном примере имя time_of_creation обнаружено в пространстве имен замыкающей функции, а print в пространстве имен встроенных функций.

Рассмотрим несколько другой пример.

Этот пример работает, основываясь на тех же механизмах, что и предыдущей, так как параметры функции — локальные переменные функции. В данном примере name — локальная переменная функции make_greeter_function , и она же является переменной из локального пространства имен замыкающей функции greet (иными словами она nonlocal для функции greet ).

Опциональные и обязательные параметры функции#

Как и в C/C++ , у параметров функции могут быть значения по умолчанию ( default value ). Такие параметры ещё называют опциональными ( optional parameter ), т.к. при вызове функции их можно не указывать, а параметры без значений по умолчаний называют обязательными ( required parameter ).

В примере выше объявлена функция say_hi_n_times с обязательным параметром name и опциональным параметром n , у которого значение по умолчанию равняется 1.

Вызвать это функцию можно двумя способами:

указав оба аргумента:

указав только обязательный параметр name и опустив опциональный n :

При объявлении функции можно указывать произвольное количество как и обязательных, так и опциональных параметров, но необходимо соблюдать следующее требование: все обязательные параметры должны быть перечислены ранее всех опциональных. Т.е. допустим только следующий синтаксис.

Нарушение этого требования — синтаксическая ошибка.

Про механизм вычисления значения по умолчанию надо помнить две детали.

Во-первых, значение по умолчанию вычисляется при объявлении функции.

Здесь f() печатает строку “before”, а не “after”, потому что на момент, когда интерпретатор читал объявление функции f и создавал соответствующий объект, имя x ссылалось на объект 5 .

Во-вторых, это значение вычисляется всего один раз. Это играет роль, если значение по умолчанию — изменяемый объект.

А здесь один и тот же список разделяется между тремя вызовами функции f . Этот список создан при объявлении функции и затем используется при всех вызовах функции без второго аргумента.

Передача аргументов в функцию по имени#

Во всех предыдущих примерах аргументы передавались в функцию позиционно, т.е. то, в какой параметр попадет значение при передаче его в качестве аргумента, определялось тем, в какой позиции он был указан при вызове функции. В python можно передавать аргументы так же и по именам параметров, нарушая при этом порядок, в котором параметры перечислены в заголовке вызываемой функции.

Для этого при вызове функции указывается имя параметра, затем знак “ = ”, а затем значение, т.е. если мы хотим передать в функцию f значение value в качестве параметра с именем x , то используется следующий синтаксис.

Это сильно увеличивает количество способов передать одни и те же аргументы в функцию. Например, в случае функции с двумя параметрами существует 4 равнозначных способа её вызвать, в том числе:

передав оба аргумента позиционно;

передав первый аргумент позиционно, а второй аргумент по имени;

передав оба аргумента по имени в том же порядке, в котором они перечисленны в определении функции;

передав оба аргумента по имени в противоположном порядке, чем порядок при котором они перечислены в определении функции.

Как и в случае с опциональными параметрами в определении функции, есть ограничение на передачу параметров по имени: необходимо сначала указать все параметры, передаваемые позиционно, а только потом все параметры, передаваемые по именам.

Нарушение этого правила — синтаксическая ошибка.

Сугубо позиционные параметры и сугубо именованные параметры#

Иногда может быть удобно сделать прием каких-то параметров только по позиции, а ряда других параметров только по имени. Для этого внутри списка параметров ставятся символы “ / ” и “ * ”:

все параметры, перечисленные до символа “ / ” считаются сугубо позиционными, т.е. передавать их можно только по позиции;

все параметры, перечисленные после символа “ * ” считаются сугубо именованными, т.е. передавать их можно только по имени;

Ниже приведена иллюстрация.

Примеры некорректных вызовов функции f .

Первый два параметра должны быть переданы по позиции.

Передано 5 позиционных аргумента, а в объявлении всего 3 параметра допускающих передачу по позиции.

Перехват произвольного количества позиционных параметров.#

Python допускает синтаксис, которые позволяет перехватывать произвольное количество позиционно переданных аргументов. Для этого при объявлении функции указывается параметр с символом “ * ” перед ним. Обычно такому параметру дают имя *args (сокращение от arguments ). Ниже приведен пример такого объявления.

Вызывать такую функцию можно передавая произвольное количество параметров.

Параметры и аргументы функций#

Цель создания функции, как правило, заключается в том, чтобы вынести кусок кода, который выполняет определенную задачу, в отдельный объект. Это позволяет использовать этот кусок кода многократно, не создавая его заново в программе.

Как правило, функция должна выполнять какие-то действия с входящими значениями и на выходе выдавать результат.

При работе с функциями важно различать:

параметры — это переменные, которые используются при создании функции.

аргументы — это фактические значения (данные), которые передаются функции при вызове.

Параметры бывают обязательные и необязательные.

Необязательные (со значением по умолчанию):

В этом случае a — передавать необязательно.

Аргументы бывают позиционные и ключевые.

Независимо от того как параметры созданы, при вызове функции им можно передавать значения и как ключевые и как позиционные аргументы. При этом обязательные параметры надо передать в любом случае, любым способом (позиционными или ключевыми), а необязательные можно передавать, можно нет. Если передавать, то тоже любым способом.

Подробнее типы параметров и аргументов будут рассматриваться позже.

Для того, чтобы функция могла принимать входящие значения, ее нужно создать с параметрами (файл func_check_passwd.py):

В данном случае, у функции два параметра: username и password.

Функция проверяет пароль и возвращает False, если проверки не прошли и True если пароль прошел проверки:

При таком определении функции надо обязательно передать оба аргумента. Если передать только один аргумент, возникнет ошибка:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *