Все статьи по Python
26 янв. 2025 г. - 14 мин. чтения
О функциях

О функциях

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

@ashtana

Штана Альберт Игоревич

Функции

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

Сложение, конкатенация, нахождение остатка от деления и остальные рассмотренные операции — это базовые возможности языков программирования. Математика не ограничена арифметикой, кроме нее есть и другие разделы со своими операциями — например, статистика. То же самое касается и строк: их можно переворачивать, менять регистр букв, удалять лишние символы — и это только самое простое. Еще на более высоком уровне есть прикладная логика конкретного приложения. Программы списывают деньги, считают налоги, формируют отчеты. Количество подобных операций бесконечно и индивидуально для каждой программы. И их нужно уметь выражать в коде. Чтобы выразить любую произвольную операцию, в программировании существует понятие функция. Функции бывают встроенные и добавленные программистом. С одной встроенной функцией мы уже знакомы — это print(). Функции — одна из ключевых конструкций в программировании. Без них невозможно сделать практически ничего. Знакомство с ними нужно начинать как можно раньше, так как весь дальнейший материал оперирует функциями по максимуму. Сначала необходимо научится пользоваться уже созданными функциями, а потом создавать собственные.

Функция len() считает количество символов в строке. Пример ее вызова:

# Вызов функции len с параметром 'Python'
result = len('Python')
print(result)  # => 6

Параметры или аргументы — это информация, которую функция получает при вызове. На основе этой информации функция обычно вычисляет и выдает результат. В примере выше мы создали переменную result и указали интерпретатору конкретное действие: надо записать в нее результат, который возвращается функцией len() при ее вызове. В этом смысле функции подобны операциям — они всегда возвращают результат своей работы. Запись len('Python') означает, что вызывается функция с именем len, в которую передали параметр 'Python'. Функция len() считает длину той строки, которую ей передали. Вызов функции всегда обозначается скобками (), которые идут сразу за именем функции. В скобках может быть любое количество параметров, а иногда ни одного. Количество зависит от используемой функции. Возьмем для примера функцию pow(), которая возводит указанное число в нужную степень. Она принимает на вход два параметра: берет первый параметр и возводит его в степень, переданную вторым параметром:

result = pow(2, 4)  # 2 * 2 * 2 * 2
print(result)  # => 16

Сигнатура функции

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

Функция pow()

Функция pow() возводит число в степень. Она принимает два параметра: какое число возводить и в какую степень возводить. Если вызывать pow() без параметров, то Python выдаст следующее: "TypeError: pow expected at least 2 arguments, got 0". Интерпретатор сообщает, что функция ожидает два параметра, а вы вызвали ее без них. Функция pow() всегда имеет два обязательных параметра, поэтому ее невозможно вызвать с другим количеством параметров. Более того, параметрами pow() могут быть только числа. Например, если передать в нее пару строк, это приведет к следующей ошибке: "TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'str'". Результат вызова функции — тоже всегда число. Другая функция может иметь другое число параметров и другие типы параметров. Например, может существовать функция, которая принимает три параметра: число, строку и еще одно число. Чтобы знать такие подробности о конкретной функции, нужно изучать ее сигнатуру. Она определяет входные параметры и их типы, а также выходной параметр и его тип. Про функцию pow() можно почитать в официальной документации Python. Обычно документация для функции выглядит так:

pow(x, y[, z])
Возвращает x в степени y; если z присутствует, возвращает x в степени y, по модулю z

Первая строка здесь — это сигнатура функции. У функции два обязательных параметра — x и y. Необязательный параметр z указан в квадратных скобках. Следом поясняется, для чего функция нужна. Документация дает понять, сколько аргументов у функции и какого они типа. Также она описывает, что возвращает функция и какого типа будет возвращаемое значение. Рассмотрим еще одну функцию — она округляет число.

Функция round()

Рассмотрим функцию round(), которая округляет переданное ей число:

result = round(9.35, 0)  # 9.0

Мы передали в нее два параметра:

  • Число, которое нужно округлить
  • Точность округления

Создатели функции round сделали второй параметр необязательным и задали ему внутри функции значение по умолчанию None. Если не указывать второй параметр, то результат будет целым значением (int):

result = round(9.23)  # 9

А если нужна точность, то можно передать параметр:

# округление до одного знака после запятой
print(round(8.25, 1))  # 8.2
print(round(8.15, 1))  # 8.2

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

Вызов функции — выражение

Можно ли вызов функции принять за выражение?

Что принимается за выражение

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

# Тут выражение — это 1 + 5
summ = 5 + 5
print(summ)

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

# Бессмысленный код, который не сработает
5 + summ = 5 + 5

Теперь разберемся, принимается ли за выражение вызов функции.

Можно ли считать вызов функции выражением

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

name = 'Python'
# Индексы начинаются с нуля
# Вызов функции и вычитание вместе!
last_i = len(name) - 1
print(last_i)  # => 5

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

name = 'Python'
print(len(name) - 1)  # => 5

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

name = 'Python'
# Используется интерполяция
print(f'Последний символ: {name[len(name) - 1]}')
# => Последний символ: n

Как вы увидите дальше, выражения можно комбинировать, получая все более сложное поведение в разных местах и любым образом. Чем глубже вы будете изучать Python и практиковаться в нем, тем лучше вы будете понимать работу с выражениями. Со временем вы лучше поймете, как соединять части кода, чтобы получить нужный результат.

Детерминированность

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

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

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

len('Python')  # 6
len('Python')  # 6
len('hex')  # 3
len('hex')  # 3

Можно бесконечно вызывать эту функцию и передавать туда значение 'Python' — она всегда вернет 6.

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

# Про синтаксис импортов позже
from random import random
# Функция, которая возвращает случайное число
random()  # 0.0432523454325265
random()  # 0.2364564577656544

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

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

Побочные эффекты

В Python есть функция print(), которая принимает на вход данные любого типа и выводит их на экран. Она вызывает побочный эффект — из-за выполнения функции запускается действие, которое изменяет среду выполнения. Ещё побочные эффекты вызывают любые сетевые взаимодействия, чтение и запись файлов, вывод информации на экран и печать на принтере. Побочные эффекты — один из основных источников проблем и ошибок в программных системах. Такой код сложнее тестировать, снижается его надежность. При этом без побочных эффектов программирование не имеет смысла. Без них было бы невозможно получить результат работы программы: например, записать в базу, вывести на экран и отправить по сети. Побочными эффектами print() отличается от других функций, которые также принимают на вход данные любого типа. Другие функции возвращают значения, которые можно дальше использовать. В отличие от них, функция print() выводит такой результат, с которым ничего нельзя сделать. Вывод на экран и возврат значения из функции — разные и независимые операции.

Попробуйте сами запустить код в окне ниже с интерпретатором Python и повторите примеры из статьи чтобы самим увидеть и понять как всё это работает. Для этого в ячейке с кодом нажмите клавиши на клавиатуре Shift+Enter или запустите код через кнопку Run по значку ▶.