Если вы уже написали несколько скриптов, то наверняка замечали: одни и те же куски кода повторяются. Хотите добавить новую возможность — приходится править в пяти местах. Знакомо? Пора познакомиться с функциями. Они позволяют собрать логику в отдельные блоки, дать им имена и вызывать тогда, когда нужно.
В этой статье разберём:
- как создать и вызвать функцию,
- что такое параметры и возвращаемое значение,
- чем отличаются локальные переменные от глобальных,
- как избежать подводных камней,
- и на реальном примере превратим игру «Угадай число» в модульный код.
1. Зачем нужны функции?
Функции решают три главные задачи:
- Повторное использование. Написал один раз — используй везде.
- Читаемость. Код разбит на логические куски с понятными именами.
- Лёгкость изменений. Исправил ошибку внутри функции — она исправляется во всех местах вызова.
Без функций код превращается в «спагетти»: длинный поток инструкций, в котором сложно ориентироваться. С функциями — становится похожим на конструктор.
2. Синтаксис: от простого к сложному
Функция создаётся ключевым словом def, затем идёт имя, скобки с параметрами и двоеточие. Тело функции пишется с отступом.
Простейшая функция
def greet():
print("Привет, мир!")
Вызов:
greet() # Привет, мир!
Функция с параметрами
def greet_person(name):
print(f"Привет, {name}!")
greet_person("Анна") # Привет, Анна!
Функция с возвратом значения
def add(a, b):
return a + b
result = add(5, 3) # result = 8
Если return не указан, функция возвращает None.
3. Параметры: гибкость на все случаи
Обязательные параметры
Их нужно передавать в том же порядке, что объявлены.
Параметры со значением по умолчанию
def greet(name, greeting="Здравствуйте"):
print(f"{greeting}, {name}!")
greet("Иван") # Здравствуйте, Иван!
greet("Иван", "Привет") # Привет, Иван!
Значения по умолчанию вычисляются один раз — это важно помнить, особенно когда в качестве значения используется изменяемый объект (список, словарь). Об этом чуть позже.
Именованные параметры
Можно передавать аргументы в любом порядке, если указать имя параметра:
greet(greeting="Привет", name="Иван")
Переменное количество аргументов
def sum_all(*args):
return sum(args)
print(sum_all(1, 2, 3, 4)) # 10
4. Возврат нескольких значений
Функция может вернуть несколько значений — они упаковываются в кортеж:
def get_user():
return "Анна", 28
name, age = get_user()
5. Области видимости: локальное vs глобальное
Переменные, созданные внутри функции, видны только внутри неё. Это локальные переменные. Чтобы изменить глобальную переменную внутри функции, нужно использовать ключевое слово global — но это считается плохой практикой. Лучше передавать данные через параметры и возвращать результаты.
x = 10 # глобальная
def change():
global x
x = 20
change()
print(x) # 20
Без global внутри функции создалась бы новая локальная переменная, а глобальная осталась бы неизменной.
6. Документирование функций
Пишите docstring — строку документации сразу после заголовка. Она помогает понять, что делает функция, и выводится через help().
def add(a, b):
"""Возвращает сумму двух чисел."""
return a + b
7. Типичные ошибки новичков
❌ Забыли return
def add(a, b):
a + b # нет return
result = add(3, 4) # result = None
❌ Неправильный порядок параметров
Если у параметра со значением по умолчанию стоят обязательные параметры справа — ошибка:
python
def greet(greeting="Здравствуйте", name): # SyntaxError
...
❌ Изменяемые объекты в качестве значения по умолчанию
def add_item(item, lst=[]):
lst.append(item)
return lst
print(add_item(1)) # [1]
print(add_item(2)) # [1, 2] — неожиданно!
Список создаётся один раз при определении функции и переиспользуется. Исправление:
def add_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
❌ Путаница между глобальными и локальными переменными
count = 0
def increment():
count += 1 # UnboundLocalError: local variable 'count' referenced before assignment
Python считает count локальной, так как она присваивается внутри. Исправление: передавать через параметры или использовать global (лучше избегать).
8. Живой пример: рефакторинг игры «Угадай число»
Вспомним игру из второй статьи. Исходный код был единым скриптом. Теперь разобьём его на функции:
import random
def get_random_number(min_val, max_val):
"""Возвращает случайное число в заданном диапазоне."""
return random.randint(min_val, max_val)
def get_user_guess():
"""Запрашивает число у пользователя, обрабатывает ошибки ввода."""
while True:
try:
return int(input("Твой вариант: "))
except ValueError:
print("Ошибка: нужно ввести целое число. Попробуй ещё раз.")
def check_guess(guess, secret):
"""Проверяет догадку и возвращает строку подсказки и булево значение (угадано ли)."""
if guess < secret:
return "Загаданное число БОЛЬШЕ.", False
elif guess > secret:
return "Загаданное число МЕНЬШЕ.", False
else:
return f"Поздравляю! Ты угадал число {secret}!", True
def play_game():
"""Основная логика игры."""
secret = get_random_number(1, 100)
print("Я загадал число от 1 до 100. Попробуй угадать!")
while True:
guess = get_user_guess()
message, is_correct = check_guess(guess, secret)
print(message)
if is_correct:
break
if __name__ == "__main__":
play_game()
Преимущества:
- каждая функция отвечает за одну задачу,
- легко тестировать и менять отдельные части,
- код стал самодокументируемым.
Заключение
Функции — это фундамент, на котором строится всё дальнейшее изучение Python. Они учат вас думать о программе как о наборе независимых компонентов. Освоив их, вы готовы к модулям, классам и настоящим проектам.
В следующей статье разберём работу с файлами: научимся сохранять данные, чтобы ваши программы не забывали информацию после закрытия. А пока — возьмите любой свой старый скрипт и попробуйте разбить его на функции. Результат вас приятно удивит.
Пишите в комментариях, какие задачи вам помогли решить функции. Обмениваемся опытом!