Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про Python: Python, default parameter, mutable default argument, dict, function

Как правильно реализовать параметр по умолчанию, если требуется изменяемый тип (например dict)?

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

Короткий ответ

В Python параметры по умолчанию вычисляются один раз в момент определения функции, а не при каждом её вызове. Если в качестве значения по умолчанию указать изменяемый объект, например, пустой словарь `{}` или список `[]`, то все вызовы функции без этого аргумента будут использовать один и тот же объект. Это приводит к накоплению данных между вызовами, что часто является ошибкой. Правильный подход — использовать `None` в качестве значения по умолчанию, а внутри функции создавать новый изменяемый объект, если аргумент не был передан.

Длинный ответ

В Python параметры функции, которым присвоено значение по умолчанию, вычисляются и создаются в момент определения функции (то есть при интерпретации кода, содержащего def), а не при каждом её вызове. Это ключевое отличие от некоторых других языков программирования. Если значением по умолчанию является изменяемый (mutable) объект, такой как список [], словарь {} или множество set(), то этот конкретный объект создаётся один раз и затем используется повторно для всех вызовов функции, где соответствующий аргумент не был указан явно.

Проблема с изменяемым параметром по умолчанию

Рассмотрим классический пример ошибочной реализации:

def add_item(item, my_list=[]):
    my_list.append(item)
    return my_list

print(add_item('a'))  # Вывод: ['a']
print(add_item('b'))  # Вывод: ['a', 'b'] - сюрприз!

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

Правильный шаблон: использование None

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

def add_item_correct(item, my_list=None):
    if my_list is None:
        my_list = []  # Создаём новый список при каждом вызове без аргумента
    my_list.append(item)
    return my_list

print(add_item_correct('a'))  # ['a']
print(add_item_correct('b'))  # ['b'] - теперь это отдельные списки

Тот же принцип применяется для словарей:

def process_data(data, config=None):
    if config is None:
        config = {}  # Новый словарь для каждого вызова
    config.setdefault('verbose', False)
    # ... обработка с использованием config
    return result

Где это применяется

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

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

Уровень

  • Рейтинг:

    4

  • Сложность:

    3

Навыки

  • Python

    Python

Ключевые слова

#Python

#default parameter

#mutable default argument

#dict

#function

Подпишись на Python Developer в телеграм