Привет! В Python можно задавать значения по умолчанию для аргументов функций. Это делает функции гибкими — одни и те же аргументы можно передавать, а можно пропускать.
В этой статье мы разберём:
- Синтаксис значений по умолчанию
- Примеры использования
- Подводные камни с изменяемыми типами
- Как избежать частых ошибок
- Что нужно знать перед началом
- Основная часть
- Синтаксис
- Несколько значений по умолчанию
- Значения по умолчанию для часто используемых параметров
- Подводный камень: изменяемые типы
- Как избежать проблемы
- Ещё один подводный камень
- Значения по умолчанию и неизменяемые типы
- Значения по умолчанию и лямбда-функции
- Задачи для закрепления
- Нюансы и подводные камни
- Значения по умолчанию вычисляются один раз
- Порядок параметров
- Частые ошибки и как их избежать
- Ошибка 1: Изменяемый тип в значении по умолчанию
- Ошибка 2: Неправильный порядок параметров
- Ошибка 3: Изменение глобальной переменной без global
- Шпаргалка
- Заключение
- КВИЗ
- Что дальше?
Что нужно знать перед началом
Для этого урока тебе понадобится:
- Установленный Python
- Базовое понимание функций
Совет: Значения по умолчанию делают код короче и удобнее.
Основная часть
Синтаксис
def имя_функции(параметр=значение_по_умолчанию):
# тело функцииПример:
def greet(name="Гость"):
print(f"Привет, {name}!")
greet() # Привет, Гость!
greet("Анна") # Привет, Анна!Совет: Параметры со значениями по умолчанию должны идти после обязательных параметров.
Несколько значений по умолчанию
def user_info(name, age=18, city="Не указан"):
print(f"Имя: {name}")
print(f"Возраст: {age}")
print(f"Город: {city}")
user_info("Анна")
# Имя: Анна
# Возраст: 18
# Город: Не указан
user_info("Иван", 25, "Москва")
# Имя: Иван
# Возраст: 25
# Город: Москва
user_info("Петр", city="Казань")
# Имя: Петр
# Возраст: 18
# Город: КазаньВажно: Параметры без значений по умолчанию всегда идут первыми
# Правильно
def func(a, b=10):
pass
# Неправильно
def func(a=10, b):
passЗначения по умолчанию для часто используемых параметров
def calculate_price(price, tax=0.05, discount=0):
total = price * (1 + tax)
total = total * (1 - discount)
return total
print(calculate_price(100)) # 105.0
print(calculate_price(100, 0.2)) # 120.0
print(calculate_price(100, discount=0.1)) # 94.5Совет: Значения по умолчанию удобны для параметров, которые не меняются в большинстве случаев.
Подводный камень: изменяемые типы
Значения по умолчанию вычисляются один раз при определении функции. Если использовать изменяемый тип (список, словарь), он будет общим для всех вызовов.
def add_item(item, items=[]):
items.append(item)
return items
print(add_item(1)) # [1]
print(add_item(2)) # [1, 2] — неожиданно!Совет: Это одна из самых частых ошибок в Python.
Как избежать проблемы
Используй None в качестве значения по умолчанию и создавай новый объект внутри функции.
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(add_item(1)) # [1]
print(add_item(2)) # [2] — правильно!Совет: Всегда используй
Noneдля изменяемых типов в значениях по умолчанию.
Ещё один подводный камень
def add_to_dict(key, value, my_dict={}):
my_dict[key] = value
return my_dict
print(add_to_dict("a", 1)) # {'a': 1}
print(add_to_dict("b", 2)) # {'a': 1, 'b': 2} — неожиданно!Исправление:
def add_to_dict(key, value, my_dict=None):
if my_dict is None:
my_dict = {}
my_dict[key] = value
return my_dictЗначения по умолчанию и неизменяемые типы
Для неизменяемых типов (числа, строки, кортежи) проблем нет.
def greet(name="Гость", age=18):
print(f"{name}, {age}")
greet() # Гость, 18
greet("Анна", 25) # Анна, 25Значения по умолчанию и лямбда-функции
# Плохо
funcs = [lambda x: x + i for i in range(3)]
print(funcs[0](1)) # 3 (не 1)
# Хорошо
funcs = [lambda x, i=i: x + i for i in range(3)]
print(funcs[0](1)) # 1Совет: В лямбда-функциях тоже нужно фиксировать значения.
Задачи для закрепления
Задача 1. Напиши функцию greet_user(name, greeting="Привет").
Задача 2. Напиши функцию calculate_discount(price, discount=10).
Задача 3. Почему использование [] как значения по умолчанию — плохая практика?
Задача 4. Как исправить проблему с изменяемым типом?
Задача 5. Напиши функцию append_to_list(item, items=None).
Ответ:
Задача 1.
def greet_user(name, greeting="Привет"):
print(f"{greeting}, {name}!")Задача 2.
def calculate_discount(price, discount=10):
return price * (1 - discount / 100)Задача 3.
# Список создаётся один раз и используется для всех вызовов.Задача 4.
# Использовать None и создавать новый список внутри функции.Задача 5.
def append_to_list(item, items=None):
if items is None:
items = []
items.append(item)
return itemsНюансы и подводные камни
Значения по умолчанию вычисляются один раз
import datetime
def log_time(time=datetime.datetime.now()):
print(time)Это не обновляет время при каждом вызове. Используй None для динамических значений.
Порядок параметров
# Правильно
def func(a, b=10, c=20):
pass
# Неправильно
def func(a=10, b, c=20):
passЧастые ошибки и как их избежать
Ошибка 1: Изменяемый тип в значении по умолчанию
Используй None.
Ошибка 2: Неправильный порядок параметров
Сначала обязательные, потом с значениями по умолчанию.
Ошибка 3: Изменение глобальной переменной без global
Используй global или передавай параметры.
Шпаргалка
| Что нужно | Как пишется |
|---|---|
| Значение по умолчанию | def func(x=10): |
| Несколько значений | def func(a, b=10, c=20): |
| Избежать изменяемого типа | def func(items=None): |
Заключение
Сегодня мы:
- Узнали, как задавать значения по умолчанию
- Разобрали подводные камни с изменяемыми типами
- Научились избегать частых ошибок
- Практические примеры








