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

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

Анализ вариантов ответов
- Вариант, который показывает
`
[1]
[2]
[1, 3]
`
совпадает с поведением кода по описанным причинам (дефолтный список один и тот же для вызовов без явного аргумента).
- Другие варианты (например, все три отдельных списока или последовательное накопление во втором вызове) не соответствуют реальному исполнению:
- Нельзя получить [1] [2] [3], если третий вызов не создаёт новый список — в данном коде дефолтный список уже содержит 1, поэтому после добавления 3 выйдет [1, 3].
- Нельзя получить [1] [2] [1, 2, 3], потому что второй вызов использует явно переданный новый список [], а не дефолтный.
Как писать безопасно: рекомендуемые паттерны
Если вы не хотите, чтобы значение сохранялось между вызовами, используйте "sentinel" None и создавайте новый список внутри функции:

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

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

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

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