Функции в python реферат

Обновлено: 05.07.2024

В предыдущих разделах мы уже часто сталкивались с встроенными функция ( int, float, print, type, len ) Каждая функция в Python предназначена для выполнения одной конкретной задачи. Использование функции упрощает написание и чтение кода.

1. Функция в Python

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

Напишем функцию, которая вычисляет квадрат своего аргумента и выводит на экран:

>>> def square ( number ):
. """Вычисление квадрата числа"""
. print(number ** 2)
.
>>> square (5)
25
>>> square (124.45)
15487.802500000002

Определение функции начинается с ключевого слова def , за которым следует имя функции - square . Имя функции, как и имена переменных рекомендуется писать с букв нижнего регистра, а в именах, состоящих из нескольких слов, составляющие должны разделяться символами подчеркивания. Далее в круглых скобках записываются параметры (аргументы) функции, разделенные запятыми. Функция square имеет только один аргумент с именем number - значение, возводимое в квадрат. В случае отсутствия параметров у функции пустые круглые скобки обязательны. В конце строки за параметрами всегда ставится двоеточие ( : ).

После двоеточия новая строка должна идти с отступом (4 пробела). Все строки с отступом образуют тело или блок функции. В "Руководстве по стилю кода Python" указано, что первой строкой блока функции должна быть doc-строка, кратко поясняющая назначение функции: """Вычисление квадрата числа""" . Сам код в теле функции состоит всего из одной строки print(number ** 2).

Команда squre(5) вызывает функции square() и передает ей значение аргумента, для выполнения команды print. Функция возводит число в квадрат и выводит на экран.

2. Передача аргументов функции в Python

2.1. Позиционные аргументы

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

>>> def car (car_brend, car_model, mileage):
. """Выводит информацию о автомобиле"""
. print(f"Продается с пробегом км.")
.
>>> car ('bmw', 'x5', 51345)
Продается Bmw X5 с пробегом 51345 км.

В данной функции видно, что должно передаваться три аргумента название автомобиля ( car_brend), модель (car_model) и пробег (mileage) . При вызове функции мы должны передать аргументы именно в том порядке, в каком они сохраняются в функции. Если нарушить порядок следования аргументов, то при вызове возможны неожиданные результаты или ошибки.

2.2. Именованные аргументы

Если порядок передачи аргументов по каким то причинам не известен, то можно использовать именованные аргументы. Именованный аргумент представляет собой пару "имя-значение". Имя и значения связываются с аргументом напрямую, так что при передаче аргумента путаница исключается. Вызовем туже самую функцию car() с помощью именованных аргументов:

>>> def car (car_brend, car_model, mileage):
. """Выводит информацию о автомобиле"""
. print(f"Продается с пробегом км.")
.
>>> car (mileage = 45152, car_model = 'x5', car_brend='bmw')
Продается Bmw X5 с пробегом 45152 км.

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

2.3. Значения по умолчанию

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

>>> def car (car_model, mileage, car_brend='bmv'):
. """Выводит информацию о автомобиле"""
. print(f"Продается с пробегом км.")
.
>>> car ('x7', 12345)
Продается Bmv X7 с пробегом 12345 км.

>>> car ('m5' , 56148)
Продается Bmv M5 с пробегом 56148 км.

Для изменения значения по умолчанию, мы можем передать именованный аргумент для изменения значения car_brend='audi':

>>> car ('q7', 35600, car_brend='audi')
Продается Audi Q7 с пробегом 35600 км.

Так как аргумент для параметра car_brend задан явно, Python игнорирует значение по умолчанию.

2.4. Передача произвольного набора аргументов

Иногда заранее не известно сколько аргументов должно быть передано функции, Python позволяет получить произвольное количество аргументов из вызывающей команды. Рассмотрим функцию, которая просто передает любое количество аргументов, к примеру название автомобилей:

>>> def cars ( * args ):
. """Вывод автомобилей"""
. print( args )
.
>>> cars ('audi', 'bmv', 'ford', 'kia')
('audi', 'bmv', 'ford', 'kia')
>>> cars ('porshe')
('porshe')

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

Для более удобной работы с данными, например изменения регистра символов можно воспользоваться циклом for:

>>> def cars ( * args):
. """Вывод автомобилей в продаже"""
. print('Автомобили в продаже:')
. for arg in args:
. print(f"-")
.
>>> cars ('audi', 'bmv', 'ford', 'kia')
Автомобили в продаже:
-Audi
-Bmv
-Ford
-Kia

2.5. Позиционные аргументы с произвольным набором аргументов

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

>>> def car (car_brend, car_model, * colors):
. """Выводит информацию о автомобиле"""
. print(f"Автомобиль можно заказать в цветах:")
. for color in colors:
. print(f"-")
.
>>> car ('bmw', 'x7', 'синий', 'зеленый', 'белый', 'черный', 'желтый')
Автомобиль Bmw X7 можно заказать в цветах:
-синий
-зеленый
-белый
-черный
-желтый

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

В большинстве программ часто используется имя обобщенного параметра *args для хранения произвольного набора позиционных аргументов.

2.6. Произвольный набор именованных аргументов

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

>>> def profile (first, last, **user_info):
. """Возвращает словарь с данными о пользователе"""
. user_info['first_name'] = first
. user_info['last_name'] = last
. return user_info
.
>>> profile_1 = profile ('tomas', 'edisson', location='usa')
>>> print(profile_1)

Функция profile ожидает получить имя и фамилию пользователя, а также позволяет передать любое количество пар "имя - значение". Две звездочки в параметре **user_info заставляют Python создать пустой словарь с именем user_info и добавить в него все полученные пары "имя - значение". В теле функции сразу добавляются имя и фамилия, а остальные пары в зависимости от переданных параметров при вызове фукции. В конце словарь возвращается с помощью команды return .

В программах часто используется имя обобщенного параметра **kwargs для хранения произвольного набора ключевых аргументов.

3. Возвращаемое значение в функции на Python

Вместо вывода результата работы напрямую, функция может обработать данные и вернуть значение c помощью команды return . Значение, возвращаемое функцией, называется возвращаемым значением.

3.1. Возвращение простого значения

Напишем функцию, которая возвращает отформатированное имя и фамилию

>>> def form_name (last_name, first_name, middle_name):
. """Возвращает отформатированное полное имя"""
. full_name = f" "
. return full_name.title()
.
>>> poet = form_name ('пушкин', 'александр', 'сергеевич')
>>> print(poet)
Пушкин Александр Сергеевич

Функция form_name получает в параметрах имя, фамилию и отечество, далее объединяет эти имена и сохраняет их в переменной full_name. Завершив выполнение, функция возвращает управление в точку вызова с помощью команды return , то есть в строку кода, которая вызывала функцию.

Предположим, что мы не знаем отчество человека, для передачи его фукции параметру middle_name. В связи с этим удобно заранее сделать в функции необязательный аргумент . Присвоим ( middle_name = "" ) пустое значение.

>>> def form_name (last_name, first_name, middle_name=''):
. """Возвращает отформатированное полное имя"""
. full_name = f" "
. return full_name.title()
.
>>> poet = form_name ('пушкин', 'александр')
>>> print(poet)
Пушкин Александр
>>> poet = form_name('пушкин', 'александр', 'сергеевич')
>>> print(poet)
Пушкин Александр Сергеевич

С необязательным аргументом мы не получим ошибку (TypeError: form_name() missing 1 required positional argument: 'middle_name') в случае отсутствия на входе данных по аргументу.

3.2. Возвращение словаря

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

>>> def info_person (first_name, last_name):
. """Возвращает словарь с данными о человеке"""
. person =
. return person
.
>>> musician = info_person ('Freddie', 'Mercury')
>>> print(musician)

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

4. Использования функции в цикле while

Функции могут вызываться в циклах while где угодно. Приведем пример цикла while, где у посетителя запрашивают имя и фамилию, а с помощью функции form_name возвращается отформатированное имя и фамилия с приветствием:

def form_name (first_name, last_name):
"""Возвращает отформатированное полное имя"""
full_name = f" "
return full_name.title()

while True:
print("\nВведите 'x' если хотите завершить программу")
first_name = input("Введите ваше имя: ")
if first_name == 'x':
break
last_name = input("Введите вашу фамилию: ")
if last_name == 'x':
break
formatted_name = form_name (first_name, last_name)
print(f"\nДобрый день !")

В данном примере в цикле whle запрашивается имя и фамилия и с помощью функции form_name возвращается отформатированное полное имя и записывается в переменную formatted_name. А затем уже с помощью функции print данные выводятся на экран.

5. Передача списка функции на Python

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

>>> def square (numbers):
. """Вычисление квадрата числа"""
. for number in numbers:
. print(number ** 2)
.
>>> numbers = [1, 5, 6, 15, -7, 1.5]
>>> square (numbers)
1
25
36
225
49
2.25

В результате функции square мы передаем список numbers. Для возведения всех чисел в квадрат, вначале нам нужно перебрать данный список с помощью цикла for, а затем каждое число возвести в квадрат.

6. Использование лямбда-выражений вместо функций

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

>>> square = lambda x : x ** 2
>>> print(square(5))
25

В начале создается переменная square и в дальнейшем по имени переменной будет вызываться лямбда-выражение. Лямбда-выражение является анонимной функцией, то есть функцией, не имеющей имени. Лямбда-выражение начинается с ключевого слова lambda , за которым следует разделенный запятыми список параметров. В нашем примере параметр один x. Затем ставится двоеточие и само выражение x ** 2. В результате при вызове переменной square мы передаем параметр число 5, и оно возводится в квадрат.

Лямбда-выражение может иметь и несколько параметров. Например, перемножать передаваемые числа.

>>> mult = lambda x, y, z : x * y * z
>>> print(mult(2, 4, 6))
48

Таким образом любая простая функция в форме

может быть выражена в более компактной форме посредством лямбда-выражения

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

Содержание

    • 1. Что такое функция? Определение функции. Преимущества применения функций
    • 2. Инструкция def . Общая форма объявления функции в Python. Создание функции
    • 3. Вызов функции
    • 4. Пример объявления и использования функции без параметров
    • 5. Пример объявления и использования функции, которая получает 1 параметр
    • 6. Пример объявления и использования функции, которая получает параметр и возвращает результат
    • 7. Пример объявления функции в инструкции if . Реализация альтернативы
    • 8. Полиморфизм в функциях. Примеры

    Поиск на других ресурсах:

    1. Что такое функция? Определение функции. Преимущества применения функций

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

    Использование функций в программах на Python дает следующие взаимосвязанные преимущества:

    • избежание повторения одинаковых фрагментов кода в разных частях программы;
    • уменьшение избыточности исходного кода программы. Как следствие, уменьшение логических ошибок программирования;
    • улучшенное восприятие исходного кода программы в случаях, где вместо блоков многочисленных инструкций (операторов) вызываются имена готовых протестированных функций. Это, в свою очередь, также уменьшает количество ошибок;
    • упрощение внесения изменений в повторяемых блоках кода, организованных в виде функций. Достаточно внести изменения только в тело функции, тогда во всех вызовах данной функции эти изменения будут учтены;
    • с помощью функций удобно разбивать сложную систему на более простые части. Значит, функции – удобный способ структурирования программы;
    • уменьшение трудозатрат на программирование, а, значит, повышение производительности работы программиста.

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

    • функции могут возвращать результат;
    • функции могут получать входные параметры, влияющие на полученный результат.
    2. Инструкция def . Общая форма объявления функции в Python. Создание функции

    Чтобы функцию можно было использовать в программе, ее нужно создать (объявить). В языке Python создание (или объявление) функции выполняется с помощью инструкции def . Если интерпретатор достигает инструкции def , он создает новый объект функции и связывает упакованный код функции с ее именем.

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

    • name – имя функции, с которым будет связан объект функции и список параметров ( arg1 , arg2 , …, argN ). Объект функции получает имя name и создается во время выполнения (в Python нет времени компиляции);
    • arg1 , arg2 , argN – список параметров, которые может получать функция. Функция также может быть без параметров;
    • statement1 , statement2 , statementN – одна или несколько инструкций, которые следуют с отступлениями относительно def .

    Если функция возвращает значение, то ее общая форма следующая

    • name – имя функции;
    • arg1 , arg2 , …, argN – параметры функции (если такие есть);
    • statement1 , statement2 , statementN – инструкции, которые реализованы в теле функции;
    • value – значение, возвращаемое функцией.

    Определение функции с помощью инструкции def может быть реализовано внутри других инструкций, например, внутри инструкции if .

    3. Вызов функции

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

    Например. Пусть объявлена следующая функция

    тогда ее вызов может быть, например, таким

    В результате, значение res = 63 .

    Интерпретатор, встретив инструкцию def выполняет следующие действия:

    • создает новый объект функции с именем Mult2 ;
    • упаковывает программный код функции и связывает объект с именем Mult2 ;
    • вызывает функцию в программе.

    то res = ‘abcabcabc’ .

    4. Пример объявления и использования функции без параметров
    5. Пример объявления и использования функции, которая получает 1 параметр

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

    Результат выполнения программы

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

    6. Пример объявления и использования функции, которая получает параметр и возвращает результат

    Ниже приводится пример функции, которая получает параметр и возвращает результат. Функция осуществляет реверсирование строки.

    Пример 2. Демонстрируется функция Summ() , которая получает два параметра a , b . Функция возвращает результат операции + над параметрами.

    9. Использование локальных переменных внутри функций. Пример

    Внутри функции могут быть объявлены локальные переменные. Локальная переменная – это имя (объект), которое доступно только внутри определения функции (инструкции def). Локальная переменная существует только во время выполнения функции.

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

    • если переменная размещается в левой части операции присваивания;
    • если переменная (имя) есть параметр (аргумент) функции;
    • если переменная есть итератором в цикле for .

    Пример. В примере создается функция SquareTriangle() , которая вычисляет площадь треугольника по его сторонам. Длины сторон треугольника с именами a , b , c есть входными параметрами функции. Если с a , b , c невозможно образовать треугольник, то функция возвращает значение None .

    Затем происходит вызов функции SquareTriangle() и обработка результата возврата из функции.

    Для определения функции нужно всего лишь написать ключевое слово def перед ее именем, а после — поставить двоеточие. Следом идет блок инструкций.

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

    Функция инкрементирует глобальную переменную i и возвращает None (по умолчанию).

    Вызовы

    Для вызова функции, которая возвращает переменную, нужно ввести:

    Для вызова функции, которая ничего не возвращает:

    Функцию можно записать в одну строку, если блок инструкций представляет собой простое выражение:

    Функции могут быть вложенными:

    Функции — это объекты, поэтому их можно присваивать переменным.

    Инструкция return

    Возврат простого значения

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

    Возврат нескольких значений

    Пока что функция возвращала только одно значение или не возвращала ничего (объект None). А как насчет нескольких значений? Этого можно добиться с помощью массива. Технически, это все еще один объект. Например:

    Аргументы и параметры

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

    Параметр — это имя в списке параметров в первой строке определения функции. Он получает свое значение при вызове. Аргумент — это реальное значение или ссылка на него, переданное функции при вызове. В этой функции:

    x и y — это параметры, а в этой:

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

    Если использовать необязательный параметр, тогда все, что указаны справа, должны быть параметрами по умолчанию.

    Выходит, что в следующем примере допущена ошибка:

    Для вызовов это работает похожим образом. Сначала нужно указывать все позиционные аргументы, а только потом необязательные:

    На самом деле, следующий вызов корректен (можно конкретно указывать имя позиционного аргумента), но этот способ не пользуется популярностью:

    А этот вызов некорректен:

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

    Можно не указывать ключевые слова, но тогда порядок имеет значение. Он должен соответствовать порядку параметров в определении:

    Если ключевые слова не используются, тогда нужно указывать все аргументы:

    Второй аргумент можно пропустить:

    Чтобы обойти эту проблему, можно использовать словарь:

    Значение по умолчанию оценивается и сохраняется только один раз при определении функции (не при вызове). Следовательно, если значение по умолчанию — это изменяемый объект, например, список или словарь, он будет меняться каждый раз при вызове функции. Чтобы избежать такого поведения, инициализацию нужно проводить внутри функции или использовать неизменяемый объект:

    Еще один пример изменяемого объекта, значение которого поменялось при вызове:

    Дабы не допустить изменения оригинальной последовательности, нужно передать копию изменяемого объекта:

    Указание произвольного количества аргументов

    Позиционные аргументы

    Иногда количество позиционных аргументов может быть переменным. Примерами таких функций могут быть max() и min() . Синтаксис для определения таких функций следующий:

    При вызове функции нужно вводить команду следующим образом:

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

    Если лишние аргументы не указаны, значением по умолчанию будет пустой кортеж.

    Произвольное количество аргументов-ключевых слов

    Как и в случае с позиционными аргументами можно определять произвольное количество аргументов-ключевых слов следующим образом (в сочетании с произвольным числом необязательных аргументов из прошлого раздела):

    При вызове функции нужно писать так:

    Python обрабатывает аргументы-ключевые слова следующим образом: подставляет обычные позиционные аргументы слева направо, а затем помещает другие позиционные аргументы в кортеж (*args), который можно использовать в функции (см. предыдущий раздел). В конце концов, он добавляет все лишние аргументы в словарь (**kwargs), который сможет использовать функция.

    Важно, что пользователь также может использовать словарь, но перед ним нужно ставить две звездочки (**):

    Порядок вывода также не определен, потому что словарь не отсортирован.

    Документирование функции

    Если изучить ее, обнаружатся два скрытых метода (которые начинаются с двух знаков нижнего подчеркивания), среди которых есть __doc__ . Он нужен для настройки документации функции. Документация в Python называется docstring и может быть объединена с функцией следующим образом:

    Команда docstring должна быть первой инструкцией после объявления функции. Ее потом можно будет извлекать или дополнять:

    Методы, функции и атрибуты, связанные с объектами функции

    Если поискать доступные для функции атрибуты, то в списке окажутся следующие методы (в Python все является объектом — даже функция):

    И несколько скрытых методов, функций и атрибутов. Например, можно получить имя функции или модуля, в котором она определена:

    Есть и другие. Вот те, которые не обсуждались:

    Рекурсивные функции

    Рекурсия — это не особенность Python. Это общепринятая и часто используемая техника в Computer Science, когда функция вызывает сама себя. Самый известный пример — вычисление факториала n! = n * n — 1 * n -2 * … 2 *1. Зная, что 0! = 1, факториал можно записать следующим образом:

    Другой распространенный пример — определение последовательности Фибоначчи:

    Важно, чтобы в ней было была конечная инструкция, иначе она никогда не закончится. Реализация вычисления факториала выше, например, не является надежной. Если указать отрицательное значение, функция будет вызывать себя бесконечно. Нужно написать так:

    Важно!
    Рекурсия позволяет писать простые и элегантные функции, но это не гарантирует эффективность и высокую скорость исполнения.

    Если рекурсия содержит баги (например, длится бесконечно), функции может не хватить памяти. Задать максимальное значение рекурсий можно с помощью модуля sys .

    Глобальная переменная

    Вот уже знакомый пример с глобальной переменной:

    Здесь функция увеличивает на 1 значение глобальной переменной i . Это способ изменять глобальную переменную, определенную вне функции. Без него функция не будет знать, что такое переменная i . Ключевое слово global можно вводить в любом месте, но переменную разрешается использовать только после ее объявления.

    За редкими исключениями глобальные переменные лучше вообще не использовать.

    Присвоение функции переменной

    С существующей функцией func синтаксис максимально простой:

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

    Менять название переменной также разрешается:

    В этом примере a1, a2 и func имеют один и тот же id. Они ссылаются на один объект.

    Практический пример — рефакторинг существующего кода. Например, есть функция sq , которая вычисляет квадрат значения:

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

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

    Теперь к ней нельзя получить доступ, а это может стать проблемой. Чтобы вернуть ее обратно, нужно просто удалить переменную:

    Анонимная функция: лямбда

    Лямбда-функция — это короткая однострочная функция, которой даже не нужно имя давать. Такие выражения содержат лишь одну инструкцию, поэтому, например, if , for и while использовать нельзя. Их также можно присваивать переменным:

    В отличие от функций, здесь не используется ключевое слово return . Результат работы и так возвращается.

    С помощью type() можно проверить тип:

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

    Изменяемые аргументы по умолчанию

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

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

    Зачем это нужно? Если у вас есть код, который используется несколько раз в рамках программы, то функция позволяет написать код один раз, а потом просто вызывать его при необходимости. Так мы не дублируем код и лучше его структурируем.

    Встроенные функции

    В Питоне есть множество встроенных в (1) стандартный функционал (built-in functions) и (2) дополнительные библиотеки (library functions) функций, и мы много раз их использовали.

    Рассмотрим функцию для создания гистограммы plt.hist(). Вначале импортируем библиотеки.

    Сгенерируем данные, которые передадим этой функции (эти же данные мы создавали и использовали на восьмом занятии вводного курса).

    Теперь построим гистограмму передав ей в качестве параметров и аргументов наши данные и количество интервалов.

    параметры функции plt.hist()

    Как мы видим, достаточно обратиться к соответствующей библиотеке ( plt ), вызвать эту функцию по имени ( hist ) и задать параметры и их аргументы ( height и bins = 10 ), и будет исполнен тот код, который заложили в нее создатели библиотеки Matplotlib.

    Теперь несколько слов про параметры и аргументы функции.

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

    Для начала определимся с терминами:

    • параметр — это то, что запрашивает функция при вызове (например, bins , количество интервалов)
    • аргумент — значение этого параметра (в нашем случае, 10 ).

    Возникает вопрос, что же такое height ? Логично предположить, что это аргумент (ведь это наши данные). Но тогда как функция узнает, какому параметру он соответствует?

    Все дело в том, что параметры и их аргументы могут быть позиционными (positional) и именованными (keyword).

    позиционные и именованные аргументы функции

    В первом случае, достаточно указать аргумент и поставить его в правильном порядке (позиции). Функция сама поймет, какой параметр ей передают. Во втором случае, нужно указать и название параметра, и аргумент.

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

    использование именованных параметров функции plt.hist()

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

    аргументы по умолчанию функции plt.hist()

    Как вы видите, результат во всех трех случаях совершенно одинаковый.

    Если вы сомневаетесь в том, какие параметры принимает функция и что является результатом ее работы, полезно обратиться к документации в Интернете. Например, по функции plt.hist() ее можно найти вот здесь⧉.

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

    Функции и методы

    Предположим, у нас есть строка, и мы хотим сделать первую букву каждого слова заглавной. Для этого у строки есть метод .title().

    А теперь попробуем применить этот метод к списку, состоящему из тех же слов, что и строка.

    ошибка при применении строкового метода .title() к списку

    Как мы видим, Питон выдал ошибку.

    Собственные функции в Питоне

    Объявление и вызов функции

    Функции не обязательно должны быть встроены в базовый функционал или библиотеки. Мы вполне можем объявлять (т.е. создавать) собственные функции (user-defined functions). Рассмотрим пример.

    Теперь давайте разберем каждый элемент этого кода. Вначале посмотрим как объявить функцию (declare a function).

    • ключевое слово def необходимо для объявления функции
    • далее идут название функции, которое вы сами определяете, и
    • параметры, которые может принимать ваша функция
    • после двоеточия на новой строке с отступом идет так называемое тело функции, то есть то, что будет исполняться при вызове функции
    • в конце ставится ключевое слово return, возвращающее результат работы функции

    Затем, когда это необходимо, мы можем вызвать функцию (call a function), указав ее имя и передав, при их наличии, соответствующие аргументы внутри круглых скобок.

    вызов собственной функции

    Пустое тело функции

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

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

    Функция print() вместо return

    Помимо ключевого слова return, результат работы функции можно вывести с помощью print().

    Хотя визуально вывод идентичен, отличие все-таки есть:

    • Использование return возвращает значение функции (в нашем случае значение переменной res) и прерывает ее работу
    • Функция print() просто выводит это значение пользователю и не влияет на дальнейшее исполнение кода, если он есть

    Параметры собственных функций

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

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

    И конечно функция может изначально не иметь параметров.

    Дополнительные возможности функций

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

    Доступны и логические операции.

    Если результатом вывода является строка, то у этой строки также есть индекс.

    Функция может не использовать параметры, но получать данные от пользователя через input().

    Появится окно для ввода числа.

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

    Введем число пять и посмотрим на результат.

    Результат вызова функции

    Функция не обязательно возвращает только число или строку, это может быть, в частности, список, кортеж или словарь. Рассмотрим несколько примеров.

    Функция может возвращать сразу несколько значений.

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

    Если записать в одну, то получится кортеж.

    Функция может возвращать и логическое значение. Давайте объявим функцию, которая проверяет четное ли ей передали число (и в этом случае вернет True) или нечетное (и тогда False).

    Использование библиотек

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

    Глобальные и локальные переменные

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

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

    Функция была вызвана без проблем. При этом если мы попробуем обратиться к переменной local_name вне этой функции, Питон выдаст ошибку.

    ошибка при вызове локальной переменной вне своей функции

    Все дело в том, что область видимости этой переменной ограничена функцией show_local_name(). Для того чтобы она была видна во всей программе, можно использовать ключевое слово global.

    Давайте посмотрим, что будет, если есть две переменные с одинаковым названием, причем одна из них глобальная, а вторая — локальная.

    При этом значение глобальной переменной для остального кода не изменится.

    Анонимные или lambda-функции

    Функции создают не только через ключевое слово def и название функции. Можно использовать слово lambda и вообще обойтись без названия. Приведем простой пример.

    Теперь давайте в деталях рассмотрим, как мы получили такой результат.

    Разумеется, ничто не мешает поместить этот же функционал в обычную функцию.

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

    Lambda-функция внутри функции filter()

    Предположим, у нас есть список чисел, и мы хотим оставить в нем только те числа, которые больше 10. Давайте решим эту задачу с помощью функции filter() и lambda-функции.

    Функция filter() принимает два параметра:

    • Во-первых, еще одну функцию, выполняющую роль критерия; она выдает True , если элемент нужно оставить, и False — если убрать
    • Во-вторых, набор элементов, которые нужно отфильтровать в виде списка, кортежа или множества

    Получив их, filter() применяет критерий (функцию) к каждому из элементов набора.

    Посмотрим на реализацию на Питоне. Вначале создадим список.

    Теперь зададим фильтрующую lambda-функцию.

    После этого поместим criterion и nums в функцию filter(). Так как сама функция filter() вернет нам не список, а специальный объект iterator, его в свою очередь нужно преобразовать обратно в список с помощью функции list().

    Чаще такой функционал записывают в одну строчку.

    И в этом и заключается удобство lambda-функции, ее не надо объявлять заранее. Через обычную функцию код выглядел бы так.

    Lambda-функция внутри функции sorted()

    Теперь рассмотрим lambda-функцию в коде, который мы использовали на занятии по рекомендательным системам. Воспроизведем в миниатюре часть решения из того занятия.

    В какой-то момент мы получили список из кортежей. И в каждом кортеже был индекс фильма и расстояние до него.

    Затем мы захотели отсортировать этот список по расстоянию, то есть по второму элементу кортежа.

    Мы взяли функцию sorted() и в качестве параметра ключа, по которому сортировать список (key), передали ей lambda-функцию, принимающей кортеж из двух элементов на входе, и выдающей второй его элемент на выходе.

    Параметр reverse = True , напомню, задает сортировку по убыванию.

    *args и **kwargs

    Прежде чем завершить, поговорим про еще одну важную тему, а именно про так называемые *args (сокращение от arguments) и **kwargs (keyword arguments).

    Они позволяют передавать функции различное количество позиционных (*args) или именованных (**kwargs) аргументов.

    Рассмотрим на примере. Начнем с *args.

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

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

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

    ошибка при использовании *args

    *args позволяет передавать функции произвольное количество отдельных чисел.

    Как вы видите, главным элементом здесь является оператор распаковки * (unpacking operator). Он принимает все передаваемые в функцию числа и формирует из них кортеж.

    Затем мы проходимся по элементам этого кортежа, рассчитываем их сумму и делим на количество элементов. Использовать слово args не обязательно, мы назвали наш позиционный аргумент nums.

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

    В этом случае мы передаем название списка со звездочкой *.

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

    **kwargs

    При использовании **kwargs происходит почти то же самое за тем исключением, что мы распаковываем именованные, а не позиционные аргументы. И распаковываем их в словарь, а не в список. Сразу посмотрим на примере.

    Приведем более сложный пример. Напишем функцию, которая на вход примет произвольное количество чисел (позиционный аргумент), преобразует в кортеж (*args) и рассчитает среднее арифметическое (mean) и среднее квадратическое отклонение (standard deviation).

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

    Вызовем функцию simple_stats() и передадим ей числа и именованные аргументы.

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

    Для того чтобы передать параметры списком и словарем, нам нужно использовать операторы распаковки * и * * соответственно.

    Количество именованных аргументов в **kwargs может быть любым. Ничто не мешает нам добавить еще один параметр.

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

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

    Подведем итог

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

    • использовать готовые функции, которые уже встроены либо в базовый функционал, либо в дополнительную библиотеку;
    • объявлять собственные функции через ключевое слово def и название функции; а также
    • создавать анонимные или lambda-функции, которые очень удобно применять там, где в полноценных собственных функциях нет необходимости

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

    Мы узнали, что у переменной может быть локальная и глобальная области видимости.

    Наконец, мы поговорили про возможность передачи различного количества позиционных и именованных аргументов через *args и **kwargs.

    Вопросы для закрепления

    Какие три вида функций мы изучили?

    Посмотреть правильный ответ

    Ответ: встроенные, собственные, а также анонимные или lambda-функции.

    Какие бывают параметры и аргументы функции?

    Посмотреть правильный ответ

    Ответ: позиционные (в этом случае мы указываем только аргумент, но ставим его в определенном порядке) и именованные (указываем и параметр, и аргумент, но порядок не важен).

    Какова область видимости локальной переменной?

    Посмотреть правильный ответ

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

    Читайте также: