Код
#статьи

Функции в Python: исчерпывающий гайд

База каждого уважающего себя питониста.

Иллюстрация: Оля Ежак для Skillbox Media

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

Содержание


Синтаксис функций

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

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

def имя_функции (аргументы):
    тело_функции
    return результат

Здесь:

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

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

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

def sum(a, b):
    return a + b

Как вызвать функцию

Функцию в Python можно создать один раз, а после вызывать её в коде неограниченное количество раз. Это позволяет экономить время и сокращает количество строк в проекте.

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

имя_функции(аргументы)

Теперь вызовем функцию для нахождения суммы, которую мы создали ранее. Для этого введём название sum и в скобках передадим переменные a и b. Результат значения запишется в переменную c:

c = sum(a, b)

Теперь рассмотрим более сложный пример. Представим, что мы хотим написать программу, которая запрашивает результаты ЕГЭ по разным предметам, считает итог и сообщает, насколько хорошо ученик справился с экзаменами.

# Запрашиваем результаты ЕГЭ
math = int(input())
russian = int(input())
informatics = int(input())

# Объявляем функцию, которая принимает результаты ЕГЭ, считает сумму и возвращает результат
def passed (math, russian, informatics):
    total = math + russian + informatics
   
    if 120 <= total < 210:
        print('Хорошо')
    elif 210 <= total < 240:
        print('Очень хорошо')
    elif total >= 240:
        print('Отлично')
    else:
        print('Неудовлетворительно')
    return total
# Вызываем функцию и выводим результат
print(passed(math, russian, informatics))

# Вывод:
40
80
80
Хорошо
200

Область видимости функций

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

Локальная область (local scope)

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

В примере ниже переменная c объявлена внутри функции sum. Её можно использовать только внутри функции, если попробовать сделать это в другом месте, то Python выдаст ошибку:

def sum(a, b):
    c = a + b
    return c

Область объемлющей функции (enclosing function scope)

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

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

def make_counter():
    # Объявляем переменную count в объемлющей функции
    count = 0

    def counter():
        # Указываем, что count находится в объемлющей функции
        nonlocal count 
        count += 1
        return count

    return counter

# Создаём счётчик
call_counter = make_counter()

# Пример использования счётчика
print(call_counter())  # Вывод: 1
print(call_counter())  # Вывод: 2
print(call_counter())  # Вывод: 3

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

Глобальная область (global scope)

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

Например, нам нужно написать программу для кондитерской, которая ведёт учёт изготовленных тортов. Каждый раз, когда мы продаём новые торты, мы будем изменять переменную cake:

# Глобальная переменная, которая обозначает количество сделанных тортов
cake_count = 10

def modify_cake():
    global cake_count
    # Изменяем значение глобальной переменной
    cake_count = 15

modify_cake()
print(modify_cake)  # Вывод: 15

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

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

Позиционные

Этот тип встречается чаще всего. Представьте книжный магазин, где уже есть разные секции: «История», «Литература», «Программирование». Сотрудники расставляют новинки по соответствующим секциям. Так будет легче найти нужную книгу.

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

# Функция принимает два аргумента в таком порядке: секция и книгаdef search(section, book): print ('Ваша книга: ', section, book) # Передаём данные в том же порядкеsearch ('История', 'История государства Российского')

Именованные

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

# Функция принимает два аргумента в таком порядке: секция и книга
def search(section, book):
    print('Ваша книга: ', section, book) 
# Передаём данные в том же порядке
search('История','История государства Российского')

Аргументы переменной длины (*args и **kwargs)

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

  • *args используют, когда неясно, сколько позиционных аргументов у нас есть. Звёздочка * перед args указывает на то, что все позиционные аргументы, переданные при вызове функции, должны быть собраны в кортеж tuple и присвоены args.
  • **kwargs используют, чтобы передать именованные аргументы в виде словаря (dictionary), когда мы не знаем, сколько их у нас. Две звёздочки (**) перед kwargs означают, что все именованные аргументы должны быть собраны в словарь и присвоены kwargs.

Например, создадим функцию greet с использованием *args и **kwargs, которая будет приветствовать людей, используя их имена и дополнительную информацию о настроении.

def greet(greeting, *args, **kwargs):
    for name in args:
        message = f'{greeting}, {name}!'
        if 'mood' in kwargs:
            message += f 'Ты чувствуешь себя {kwargs['mood']}.'
        print(message)

# Пример использования
greet('Привет', 'Катя', 'Лена', 'Вика', mood= 'весело')
greet('Здравствуйте', 'Саша, 'Таня')

Функция greet принимает приветствие, список имён *args и дополнительные параметры **kwargs. Проходит через каждое имя в args и формирует приветственное сообщение. Если в kwargs есть ключ mood, то в сообщение добавляется информация о настроении.

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

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

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

def greet(name = 'Посетитель', message = 'Привет, '):
    print(message, name)

# Вызов функции без указания значения по умолчанию
greet()  # Вывод: Привет, Посетитель

# Вызов функции с изменённым значением по умолчанию
greet('Артём')  # Вывод: Привет, Артём

В этом примере функция greet принимает два аргумента: name и message. У аргумента message значение по умолчанию Привет, а у nameпосетитель. Если при вызове функции не указывается значение, то используется значение по умолчанию.

Передача по значению и по ссылке

Один из частых вопросов, который волнует новичков в Python, — как передаются переменные в функции и методы: по значению или по ссылке.

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

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

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

Пример:

def add_item(my_list, item):
    # Изменяем переданный список
    my_list.append(item)

numbers = [1, 2, 3]
add_item(numbers, 4)
print(numbers)  # Вывод: [1, 2, 3, 4]

Здесь видно, что мы внесли изменения в список, когда взяли его в качестве аргумента, и он теперь выглядит по-другому.

Словарь в качестве аргументов

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

Например, переменную можно использовать, чтобы выводить персональную информацию для каждого пользователя интернет-магазина. У кого-то будут заполнены графы Ф. И. О., Возраст и Место жительства, а кто-то поленился указать город ― тогда можно вывести только ту информацию, что есть.

def print_person_info(**kwargs):
    print(f'Имя: {kwargs.get('name')}')
    print(f'Возраст: {kwargs.get('age')}')

# Передача словаря в качестве именованных аргументов
person_1 = {'name': 'Аня', 'age': 10}
person_2 = {'name': 'Борис'}
person_3 = {'age': 12}
person_4 = {}
print_person_info(**person_1)

Возвращаемые значения (return)

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

В примере ниже функция add принимает два аргумента a и b, складывает их и с помощью return возвращает сумму a + b:

def add(a, b):
    return a + b

result = add(3, 5)
print(result)  # Вывод: 8

Если не использовать в функции ключевое слово return, она по умолчанию вернёт None.

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

Модуль random в Python

Lambda-функции

Лямбда-функции (lambda-функции) ― это безымянные функции, которые могут быть определены в одной строке кода. Выше мы упомянули, что название функции используют, чтобы вызвать функцию повторно. Лямбда-функцию нельзя переиспользовать ― у неё нет имени, по которому её можно вызвать. Обычно их используют там, где требуется передать небольшую функцию в качестве аргумента.

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

lambda аргументы: выражение

В качестве примера рассмотрим лямбда-функцию, которая проверяет чётность числа и выводит True или False. В качестве параметра передаётся переменная num, а после двоеточия указано выражение num % 2 == 0:

is_even = lambda num: num % 2 == 0

print(is_even(4))  # Вывод: True
print(is_even(7))  # Вывод: False

Процедуры и функции: различия

Слова «процедура» и «функция» в Python часто обозначают одно и то же — блок кода для выполнения определённой задачи. Однако есть различия.

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

Например, greet из примеров выше ― это процедура, которая принимает имя в качестве аргумента и выводит приветствие на экран. Она не возвращает никакого значения: её цель только выполнить действие.

  • Функция ― тоже фрагмент кода, который выполняет определённую задачу или действие. Но она возвращает результат с помощью ключевого слова return.

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

Что в итоге

  • Функции в Python объявляют с помощью ключевого слова def, за которым следует имя функции, круглые скобки для аргументов и двоеточие. Тело функции пишется с отступом.
  • Python поддерживает несколько видов аргументов в функциях, включая позиционные, именованные, аргументы со значением по умолчанию, а также переменное количество аргументов с помощью *args и **kwargs.
  • Локальные переменные видны только внутри функции, глобальные доступны во всём коде, а вложенные функции имеют доступ к переменным друг друга.
  • Функции могут возвращать значения с помощью ключевого слова return. Если оно отсутствует, то функция возвращает None.
  • Помимо стандартных функций, Python поддерживает создание анонимных функций с помощью ключевого слова lambda, они могут содержать лишь одно выражение.
  • В Python нет явного различия между функциями и процедурами.

Больше интересного про код — в нашем телеграм-канале. Подписывайтесь!


Изучайте IT на практике — бесплатно

Курсы за 2990 0 р.

Я не знаю, с чего начать
Научитесь: Профессия Python-разработчик Узнать больше
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована