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

Что здесь происходит (интуиция и правило)
В Python значение аргумента по умолчанию вычисляется один раз — в момент определения функции. Если это мутабельный объект (например, список, словарь), то один и тот же объект будет использован для всех последующих вызовов, где аргумент не передан. В нашем примере список lst сохраняется между вызовами, и второй вызов продолжит модифицировать тот же список.
Демонстрация

Ожидаемый вывод (примерный):

Как видно, второй вызов добавляет ещё один элемент в тот же список, поэтому b становится [1, 1], а объекты a и b указывают на один и тот же список.
Разбор вариантов ответа
- "Оба вызова вернут [1]" — не соответствует наблюдаемому поведению, поскольку второй вызов добавляет ещё один элемент.
- "Первый — [1], второй — [1, 1]" — описывает именно поведение, возникающее при использовании мутабельного аргумента по умолчанию в данном коде.
- "Первый — [], второй — [1]" — неверно: первый вызов добавляет 1 в дефолтный список, поэтому он не остаётся пустым.
- "Оба вернут один и тот же объект [1, 1]" — неверно формулировано: после двух последовательных вызовов объект будет один и тот же, но первый вызов вернёт
[1]в момент получения; после второго вызова значение этого же объекта изменится на[1, 1].
(Важный нюанс: если вы посмотрите на возвращаемую ссылку a после выполнения второго вызова, её содержимое тоже покажет [1, 1], потому что это тот же объект. Но в момент получения a сразу после первого вызова он был [1].)
Как избежать нежелательного поведения
Стандартный шаблон — использовать None как значение по умолчанию и создавать новый список внутри функции:

Проверка:

Теперь каждый вызов без аргумента получает новый список.
Когда такое поведение может быть полезно
Иногда хранение состояния между вызовами — желаемое поведение (например, кеширование, накапливание). Тогда использование мутабельного аргумента по умолчанию — компактный приём, но лучше документировать намерение явно или использовать замыкания/классы:

Или класс с полем состояния.
Вывод
Мутабельные аргументы по умолчанию в Python не пересоздаются при каждом вызове функции — они вычисляются один раз при определении функции и затем повторно используются. Это часто приводит к сюрпризам (как в приведённом примере), поэтому безопаснее применять паттерн с None или явно документировать и использовать накопительное поведение.