Мутабельный аргумент по умолчанию в Python

Мутабельный аргумент по умолчанию в Python

@python_quiz

Разберем этот квиз

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

Условие (фрагмент кода)

python

Пошаговый разбор выполнения

  1. Когда функция определена, значение аргумента items=[] создаётся один раз и хранится как объект по умолчанию.
  2. Первый вызов add_item(1) использует этот дефолтный список и добавляет в него 1. Теперь дефолтный список равен [1]. Функция возвращает [1].
  3. Второй вызов add_item(2, []) явно передаёт новый пустой список в качестве аргумента. В этот отдельный список добавляется 2 и получается [2]. Дефолтный список при этом не меняется.
  4. Третий вызов add_item(3) снова использует тот самый дефолтный список, который уже содержит [1]. В него добавляется 3, он становится [1, 3].

В итоге вывод программы будет:

python

Анализ вариантов ответов

  • Вариант, который показывает

`
[1]
[2]
[1, 3]
`
совпадает с поведением кода по описанным причинам (дефолтный список один и тот же для вызовов без явного аргумента).

  • Другие варианты (например, все три отдельных списока или последовательное накопление во втором вызове) не соответствуют реальному исполнению:

- Нельзя получить [1] [2] [3], если третий вызов не создаёт новый список — в данном коде дефолтный список уже содержит 1, поэтому после добавления 3 выйдет [1, 3].
- Нельзя получить [1] [2] [1, 2, 3], потому что второй вызов использует явно переданный новый список [], а не дефолтный.

Как писать безопасно: рекомендуемые паттерны

Если вы не хотите, чтобы значение сохранялось между вызовами, используйте "sentinel" None и создавайте новый список внутри функции:

python

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

python

Если же вам нужен именно накопительный эффект между вызовами (редкий, но возможный кейс), можно документировать это поведение или использовать явное глобальное состояние/класс:

python

Или явно хранить состояние в объекте:

python

Выводы — коротко

  • Аргументы по умолчанию вычисляются один раз при определении функции.
  • Использование изменяемых объектов (список, словарь и т.п.) как значений по умолчанию часто приводит к неожиданным побочным эффектам.
  • Обычно безопаснее использовать None в качестве значения по умолчанию и создавать новый объект внутри функции.

Report Page