Что такое функции в Python

Функция — это именованный участок кода. Иначе говоря, мы выделяем какой-то кусок нашего кода и даём ему имя.

Например:

print('Привет!')
# Привет!

Функция print() выводит на экран нашу строку “Привет!”. Мы не знаем как она это делает, но мы точно знаем что именно произойдёт. Где-то далеко-далеко в питоне какой-то программист написал код этой функции, и вы пользуетесь ею даже не вникая как именно он текст выводиться в терминал.

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

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

Давайте решим простую задачу: у вас есть магазин продуктов. Вы хотите продавать в нём молоко по 100 рублей за бутылку. Но при этом вы ещё должны платить 20% от стоимости проданных товаров в налоговую. Этот налог называется НДС, вы наверняка видели его в чеках. Вопрос: какую цену поставить в ценник, чтобы после уплаты налогов вы получали по 100 рублей за бутылку?

Вот фрагмент кода, который решает эту задачу:

# Хотим посчитать цену с НДС для пачки молока
milk_price = 100
vat_rate = 20  # VAT — НДС, 20% — ставка НДС в России.
vat = milk_price * vat_rate / 100  # Налог
milk_price_with_vat = milk_price + vat  # Цена с налогом
print(milk_price_with_vat)  # 120 рублей

А теперь вспоминаем, что в магазине помимо молока есть ещё макароны. Пишем аналогичный код для расчёта ценника макарон:

spaghetti_price = 150
vat_rate = 20
vat = spaghetti_price * vat_rate / 100
spaghetti_price_with_vat = spaghetti_price + vat
print(spaghetti_price_with_vat)  # 180 рублей

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

  1. Если изменится размер НДС, код придётся править уже в двух местах
  2. Если допустили ошибку при расчёте, то её тоже придётся исправлять в двух разных местах
  3. Новой логики не добавляется, а кода становится больше
  4. Представьте сколько товаров в магазине! И для каждого нужно 5 строчек???

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

def get_price_with_vat(price):
    vat_rate = 20
    vat = price * vat_rate / 100
    price_with_vat = price + vat
    return price_with_vat
    
milk_price_vat = get_price_with_vat(100)  # 120
spaghetti_price_vat = get_price_with_vat(150)  # 180

Весь код по подсчёту цены с НДС спрятан в функцию get_price_with_vat. Остаётся только подставлять в неё разные числа и получать готовые ценники для разных товаров.

Теперь давайте посмотрим как написать свою функцию. Разберём get_price_with_vat по частям:

Сигнатура

sample_text

Сигнатура функции пишется в самом начале. Она состоит из:

  1. Ключевого слова def, которое говорит питону о том, что здесь мы начинаем писать новую функцию.
  2. Названия функции.
  3. Параметров, иначе говоря входных данных, необходимых для работы функции.

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

Тело функции

sample_text

Здесь всё просто: это тот код, который мы хотим поместить в функцию. Обратите внимание, код тела функции мы пишем с отступом от левого края строки. В питоне принято таким образом помечать какой код относится к функции, а какой — нет. Это правило установлено на уровне языка, поэтому если отступов не сделать — программа сломается. В дальнейшем, вы ещё встретитесь с отступами. Размер одно отступа — 4 пробела.

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


def get_price_with_vat(price):
    vat_rate = 20
    vat = price * vat_rate / 100
    price_with_vat = price + vat
    return price_with_vat
    
get_price_with_vat(100)
print(vat_rate)  # NameError: name 'vat_rate' is not defined

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

Возвращаемое значение

sample_text

Для возврата желаемого значения во внешний мир, используется ключевое слово return:

def get_price_with_vat(price):
    vat_rate = 20
    vat = price * vat_rate / 100
    price_with_vat = price + vat
    return price_with_vat  # price_with_vat равно 120
    
result = get_price_with_vat(100)
print(result)  # 120

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


def get_price_with_vat(price):
    vat_rate = 20
    vat = price * vat_rate / 100
    price_with_vat = price + vat
    # тут удалили строку
    
result = get_price_with_vat(100)
print(result)  # None

Функция len() всегда возвращает длину переданного ей параметра, а функция print() - возвращает None. Из функции можно вернуть несколько значений, для этого перечислить их все через запятую:

def get_vat_and_price_with_vat(price):
    vat_rate = 20
    vat = price * vat_rate / 100
    price_with_vat = price + vat
    return vat, price_with_vat
    
vat, price = get_vat_and_price_with_vat(100)
print(vat)  # 20
print(price)  # 120

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


def return_interrupt_example():
    print('Это фраза всегда будет печататься на экране')
    somevalue = 1000
    return somevalue
    print('А эта - никогда')
    
return_interrupt_example()

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

Что ещё почитать


Попробуйте бесплатные уроки по Python

Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.

Переходите на страницу учебных модулей «Девмана» и выбирайте тему.