Функция — это блок кода, который решает конкретную задачу и может вызываться многократно. Вместо того чтобы копировать одни и те же строки в разных местах программы, вы описываете логику один раз в функции, а потом просто «зовёте» её, когда нужно.
Как объявить функцию
Для объявления функции используют ключевое слово def, затем имя функции, скобки с параметрами (если они нужны) и двоеточие. Тело функции пишут с отступом.
def приветствие(имя): print(f"Привет, {имя}!")
Вызов:
приветствие("Анна") приветствие("Борис")
Вывод:
Привет, Анна!
Привет, Борис!
Здесь логика «напечатать приветствие» описана один раз, но используется дважды.
Возврат значения: return
Если функция должна не просто что-то показать, а выдать результат для дальнейшей работы, используют return. После return функция останавливается, и код ниже не выполняется.
def квадрат(x): return x * x
Использование:
a = квадрат(3) b = квадрат(5) print(a, b)
Вывод:
9 25
Теперь результат можно сохранять в переменные, передавать в другие функции, складывать и т. д.
Параметры по умолчанию
Иногда удобно задать значения, которые будут использоваться, если при вызове параметр не передали.
def формат_цены(сумма, валюта="руб."): return f"{сумма} {валюта}"
Примеры вызова:
print(формат_цены(100)) print(формат_цены(200, "USD"))
Вывод:
100 руб. 200 USD
Это делает функцию гибче: не нужно каждый раз указывать валюту, если она стандартная.
Позиционные и именованные аргументы
При вызове можно передавать аргументы по порядку (позиционно) или по имени.
def создать_заказ(товар, количество, статус="новый"): return f"Заказ: {количество} шт. {товар}, статус: {статус}"
Варианты вызова:
# Позиционные print(создать_заказ("кофе", 3)) # Именованные (порядок не важен) print(создать_заказ(количество=2, товар="чай", статус="в обработке"))
Вывод:
Заказ: 3 шт. кофе, статус: новый Заказ: 2 шт. чай, статус: в обработке
Именованные аргументы особенно полезны, когда параметров много: так код легче читать и сложнее перепутать значения.
Переменное число аргументов: *args и **kwargs
Когда заранее неизвестно, сколько значений передадут, используют *args (кортеж аргументов) и **kwargs (словарь именованных аргументов).
*args — список значений
def сумма_всех(*числа): total = 0 for n in числа: total += n return total
Вызовы:
print(сумма_всех(1, 2, 3)) print(сумма_всех(10, 20, 30, 40))
Вывод:
6 100
**kwargs — именованные параметры
def показать_настройки(**настройки): for ключ, значение in настройки.items(): print(f"{ключ}: {значение}")
Вызов:
показать_настройки(тема="тёмная", шрифт="14px", язык="ru")
Вывод:
тема: тёмная шрифт: 14px язык: ru
На практике *args и **kwargs чаще всего используют, когда пишут утилиты, декораторы или обёртки над другими функциями.
Практический пример: функция для валидации возраста
Допустим, нужно проверять, что возраст находится в диапазоне 0–120. Эту проверку придётся делать в разных местах — лучше вынести в функцию.
def проверить_возраст(возраст): if not isinstance(возраст, int): return False, "Возраст должен быть целым числом" if возраст < 0 or возраст > 120: return False, "Возраст вне допустимого диапазона (0–120)" return True, "OK"
Использование в разных местах:
ok, сообщение = проверить_возраст(25) if ok: print("Возраст корректен") else: print("Ошибка:", сообщение) ok2, сообщение2 = проверить_возраст(-5) if not ok2: print("Ошибка:", сообщение2)
Вывод:
Возраст корректен Ошибка: Возраст вне допустимого диапазона (0–120)
Логика проверки написана один раз, а используется в нескольких местах. Если позже диапазон изменится, достаточно поправить код в одном месте.
Частые ошибки и как их избежать
- Забыли
return, а ждут результат.
Функция безreturnвозвращаетNone.pythondef удвоить(x): x * 2 # результат никуда не сохраняется и не возвращается r = удвоить(5) # r будет None
Правильно:
pythondef удвоить(x): return x * 2
- Изменяемые объекты как параметры по умолчанию.
Не делайте так:pythondef добавить_элемент(элемент, список=[]): список.append(элемент) return список
Список
[]создаётся один раз при определении функции, и между вызовами он «помнит» предыдущие элементы.
Правильный вариант:pythondef добавить_элемент(элемент, список=None): if список is None: список = [] список.append(элемент) return список
Пример: функция для расчёта скидки
Задача: посчитать итоговую цену с учётом скидки в процентах. Скидка может отсутствовать, тогда она равна 0.
def итоговая_цена(базовая, скидка_проц=0): скидка = базовая * скидка_проц / 100 return базовая - скидка
Вызовы:
print(итоговая_цена(1000)) # без скидки print(итоговая_цена(1000, 10)) # скидка 10% print(итоговая_цена(2500, скидка_проц=20)) # именованный аргумент
Вывод:
1000.0 900.0 2000.0
Такой подход делает код чище: логика расчёта скрыта внутри функции, а в основном коде остаются только понятные вызовы.
Когда стоит выносить код в функцию
- Если один и тот же фрагмент встречается в двух и более местах — вынесите в функцию.
- Если блок кода решает понятную подзадачу (проверка, форматирование, расчёт) — функция сделает его смысл яснее.
- Если позже может понадобиться изменить логику — функция позволит сделать это в одном месте, а не править код по всему проекту.
Вывод
Функции позволяют:
- не дублировать код;
- делать логику понятнее за счёт осмысленных имён;
- менять поведение в одном месте вместо правки во многих;
- переиспользовать готовые решения в разных задачах.
Чем раньше начать группировать повторяющиеся действия в функции, тем проще будет поддерживать и расширять программу.
