Хостинг SpaceWeb
Серверы Дизайн Сайты Безопасность Домены PHP Кейсы клиентов

Функции в Python: полный разбор с примерами

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

Что такое функции в Python и для чего они нужны

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

Зачем они нужны:

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

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

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

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

Общая структура функции выглядит так:

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

Где:

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

Виды функций в Python

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

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

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

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

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

Полный список встроенных функций Python:

Функция Описание
abs() Возвращает абсолютное значение числа (модуль)
aiter() Возвращает асинхронный итератор для объекта
all() Возвращает True, если в последовательности нет ложных значений (или если она пустая)
anext() Получает следующий элемент из асинхронного итератора (аналог next() для обычного итератора)
any() Возвращает True, если есть хотя бы одно истинное значение (или False, если все ложные)
ascii() Возвращает строку с представлением объекта, заменяя не-ASCII символы на escape-последовательности
bin() Преобразует целое число в строку с двоичным представлением
bool() Преобразует объект в True или False
breakpoint() Устанавливает точку остановки (запускает отладчик)
bytearray() Создает изменяемый массив байтов
bytes() Создает неизменяемый объект байтов
callable() Проверяет, можно ли вызвать объект (функция ли это и т. д.)
chr() Возвращает символ по его числовому коду (например, chr(65) == 'A')
classmethod() Преобразует метод класса в метод, который получает сам класс в качестве первого аргумента
compile() Компилирует строку или AST в объект кода, готовый к исполнению
complex() Создает комплексное число из двух чисел (действительной и мнимой частей)
delattr() Удаляет указанный атрибут у объекта
dict() Создает словарь (пустой или из набора пар «ключ: значение»)
dir() Возвращает список имен атрибутов и методов объекта
divmod() Возвращает кортеж (частное, остаток) от целочисленного деления
enumerate() Возвращает итератор пар (индекс, значение) для итерируемого
eval() Вычисляет строку как выражение Python и возвращает результат
exec() Выполняет динамически сформированный код Python
filter() Фильтрует элементы итерируемого по функции-предикату, возвращая только те, для которых функция вернула True
float() Преобразует значение в число с плавающей точкой
format() Форматирует значение согласно спецификации (аналог f-строк или метода .format())
frozenset() Создает неизменяемое множество (его нельзя изменить после создания)
getattr() Получает значение атрибута объекта по имени (строке)
globals() Возвращает словарь текущего глобального пространства имен
hasattr() Проверяет, существует ли у объекта атрибут с указанным именем
hash() Возвращает хеш-значение объекта (для использования в словарях и множествах)
help() Выводит справочную информацию по объекту или модулю
hex() Преобразует целое число в строку с шестнадцатеричным представлением
id() Возвращает уникальный идентификатор объекта в текущем сеансе Python
input() Считывает строку из стандартного ввода (обычно — консоли)
int() Преобразует значение в целое число
isinstance() Проверяет, является ли объект экземпляром указанного класса или кортежа классов
issubclass() Проверяет, является ли один класс подклассом другого
iter() Возвращает итератор для указанного итерируемого объекта
len() Возвращает число элементов в объекте (длину последовательности, количество ключей в словаре и т. д.)
list() Создает список (пустой или из итерируемого)
locals() Возвращает словарь текущего локального пространства имен
map() Применяет функцию к каждому элементу итерируемого и возвращает итератор результатов
max() Возвращает наибольший элемент итерируемого или наибольшее из переданных аргументов
memoryview() Создает «вид» на объект байтов без копирования данных
min() Возвращает наименьший элемент итерируемого или наименьшее из переданных аргументов
next() Возвращает следующий элемент итератора, вызывает StopIteration, если элементов больше нет
object() Создает базовый, самый «пустой» объект в Python
oct() Преобразует целое число в строку с восьмеричным представлением
open() Открывает файл и возвращает файловый объект для чтения/записи
ord() Возвращает числовой код символа (аналог chr())
pow() Возводит число в степень (аналог x**y), может принимать третий аргумент — модуль
print() Выводит переданные значения в стандартный поток вывода (консоль)
property() Создает свойство для управления доступом к атрибутам класса
range() Возвращает итерируемую последовательность чисел по заданному диапазону
repr() Возвращает строковое представление объекта, удобное для разработчика (часто может быть введено обратно в Python)
reversed() Возвращает итератор элементов итерируемого в обратном порядке
round() Округляет число до заданного количества знаков после запятой
set() Создает множество (уникальный набор элементов)
setattr() Устанавливает или изменяет атрибут объекта по имени
slice() Создает объект среза, который можно применять к последовательностям
sorted() Возвращает новый отсортированный список из элементов итерируемого
staticmethod() Превращает метод класса в статический — не принимает ни self, ни cls
str() Преобразует объект в строку
sum() Возвращает сумму элементов итерируемого (начальное значение можно задать вторым аргументом)
super() Позволяет обращаться к методам родительского класса из подкласса
tuple() Создает кортеж (неизменяемую последовательность)
type() Возвращает тип объекта или создает новый класс при трех аргументах
vars() Возвращает словарь атрибутов объекта или текущего пространства имен
zip() Объединяет несколько итерируемых, возвращая итератор кортежей из элементов на одинаковых позициях
__import__() Внутренняя функция импорта модуля. Используется интерпретатором, но доступна и для кода

Пример:

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

grades = [72, 85, 90, 64, 100, 77]
print("Количество студентов:", len(grades))
print("Максимальная оценка:", max(grades))
print("Минимальная оценка:", min(grades))
print("Сортировка по возрастанию:", sorted(grades))

Результат выполнения:

Количество студентов: 6
Максимальная оценка: 100
Минимальная оценка: 64
Сортировка по возрастанию: [64, 72, 77, 85, 90, 100]

Здесь мы использовали сразу несколько встроенных функций:

Без встроенных функций пришлось бы писать дополнительные циклы и условия. А так все решается быстро и читается максимально просто.

Пользовательские функции

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

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

Пример:

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

grades = [72, 85, 90, 64, 100, 77]
def average_grade(grades_list):
    total = sum(grades_list)
    count = len(grades_list)
    return total / count
print("Средний балл:", average_grade(grades))

Результат выполнения:

Средний балл: 81.33333333333333

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

Анонимные функции

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

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

Анонимные функции удобно применять:

Пример:

У нас есть список студентов с их баллами. Нужно отсортировать их по оценке от большего к меньшему:

students = [
    ("Анна", 72),
    ("Борис", 85),
    ("Виктор", 90),
    ("Даша", 64),
    ("Ирина", 100),
    ("Сергей", 77)
]
# Отберем только студентов, у которых балл 80 и выше
passed = list(filter(lambda x: x[1] >= 80, students))
print("Студенты с результатом 80 и выше:", passed)

Результат выполнения:

Студенты с результатом 80 и выше: [('Борис', 85), ('Виктор', 90), ('Ирина', 100)]
Здесь lambda x: x[1] >= 80 проверяет второй элемент кортежа (оценку), и в итоговый список попадают только те студенты, кто сдал экзамен на 80+.

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

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

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

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

Пример:

Допустим, оценки студентов хранятся не в одном списке, а в виде вложенных списков — по группам. Мы хотим найти общую сумму баллов.

grades = [
    [72, 85, 90],      # Группа 1
    [64, 100, 77],     # Группа 2
    [88, 95]           # Группа 3
]
def recursive_sum(data):
    total = 0
    for item in data:
        if isinstance(item, list):         # Если внутри список — вызываем функцию снова
            total += recursive_sum(item)
        else:                              # Если число — просто прибавляем
            total += item
    return total
print("Общая сумма баллов:", recursive_sum(grades))

Результат выполнения:

Общая сумма баллов: 671

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

Функции высшего порядка

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

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

Классические примеры функций высшего порядка в Python — map(), filter() и reduce().

Пример:

Как раз здесь и актуальны функции высшего порядка filter() и map().

students = [
    ("Анна", 72),
    ("Борис", 85),
    ("Виктор", 90),
    ("Даша", 64),
    ("Ирина", 100),
    ("Сергей", 77)
]
# filter — оставляем только студентов, у которых балл 80 и выше
passed = list(filter(lambda x: x[1] >= 80, students))
# map — преобразуем оценки в проценты (от 0 до 1)
percentages = list(map(lambda x: (x[0], x[1] / 100), students))
print("Студенты, сдавшие экзамен:", passed)
print("Оценки в процентах:", percentages)

Результат выполнения:

Студенты, сдавшие экзамен: [('Борис', 85), ('Виктор', 90), ('Ирина', 100)]
Оценки в процентах: [('Анна', 0.72), ('Борис', 0.85), ('Виктор', 0.9), ('Даша', 0.64), ('Ирина', 1.0), ('Сергей', 0.77)]

Где:

Асинхронные функции

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

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

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

Пример:

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

import asyncio
students = [
    ("Анна", 72),
    ("Борис", 85),
    ("Виктор", 90)
]
async def fetch_grade(student):
    print(f"Загружаю данные для {student[0]}...")
    await asyncio.sleep(1)  # имитация задержки при запросе
    print(f"Данные получены: {student[1]}")
    return student
async def main():
    tasks = [fetch_grade(student) for student in students]
    results = await asyncio.gather(*tasks)
    print("Все данные загружены:", results)
asyncio.run(main())

Результат выполнения:

Загружаю данные для Анна...
Загружаю данные для Борис...
Загружаю данные для Виктор...
Данные получены: 72
Данные получены: 85
Данные получены: 90
Все данные загружены: [('Анна', 72), ('Борис', 85), ('Виктор', 90)]

Генераторные функции

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

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

Главное преимущество генераторов — экономия памяти. Они не хранят все данные целиком, а создают их по мере необходимости.

Пример:

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

students = [
    ("Анна", 72),
    ("Борис", 85),
    ("Виктор", 90),
    ("Даша", 64),
    ("Ирина", 100)
]
def grade_generator(students_list):
    for student in students_list:
        yield student
# Используем генератор
for s in grade_generator(students):
    print(f"{s[0]} получил(а) {s[1]} баллов")

Результат выполнения:

Анна получил(а) 72 баллов
Борис получил(а) 85 баллов
Виктор получил(а) 90 баллов
Даша получил(а) 64 баллов
Ирина получил(а) 100 баллов

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

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

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

В Python существует несколько типов аргументов:

По умолчанию

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

Пример:

def student_info(name, group="Не указана"):
    print("Имя:", name)
    print("Группа:", group)
student_info("Анна")
student_info("Борис", "ИСТ-21")

Результат выполнения:

Имя: Анна
Группа: Не указана
Имя: Борис
Группа: ИСТ-21

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

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

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

Пример:

def student(fname, lname):
    print("Имя:", fname)
    print("Фамилия:", lname)
student(fname="Иван", lname="Петров")
student(lname="Петров", fname="Иван")

Результат выполнения:

Имя: Иван
Фамилия: Петров
Имя: Иван
Фамилия: Петров

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

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

Пример:

def student_info(name, age):
    print("Имя:", name)
    print("Возраст:", age)
print("Вызов 1:")
student_info("Анна", 20)
print("\nВызов 2:")
student_info(20, "Анна")

Результат выполнения:

Вызов 1:
Имя: Анна
Возраст: 20
Вызов 2:
Имя: 20
Возраст: Анна

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

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

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

Пример:

def show_info(*args, **kwargs):
    print("Позиционные аргументы (*args):")
    for arg in args:
        print(arg)
    print("\nИменованные аргументы (**kwargs):")
    for key, value in kwargs.items():
        print(f"{key} = {value}")
show_info("Анна", "Борис", group="ИСТ-21", course=2)

Результат выполнения:

Позиционные аргументы (*args):
Анна
Борис
Именованные аргументы (**kwargs):
group = ИСТ-21
course = 2

Таким образом, функция принимает любое количество аргументов. Сначала в нее попадают все значения без имени (Анна, Борис), а потом — пары «ключ = значение» (group, course).

Как использовать результат функции в другой функции

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

Пример:

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

students = [
    ("Анна", 72),
    ("Борис", 85),
    ("Виктор", 90),
    ("Даша", 64),
    ("Ирина", 100),
    ("Сергей", 77)
]
def average_grade(data):
    """Вычисляет средний балл студентов"""
    total = sum([x[1] for x in data])
    return total / len(data)

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

def show_average(calc_function, dataset):
    print("Средний балл:", calc_function(dataset))
show_average(average_grade, students)

Результат выполнения:

Средний балл: 81.33333333333333

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

Советы по использованию функций в Python

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

Заключение

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

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

Перейти на оригинал