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

Что печатает код
При запуске программа выведет:

То есть первый вызов возвращает список с одним элементом, второй — с двумя элементами, причём первый элемент сохраняется между вызовами.
Почему так происходит — объяснение механизма
- Значение аргументов по умолчанию в Python вычисляется один раз — в момент определения функции, а не при каждом вызове.
- Если значение по умолчанию — изменяемый объект (список, словарь, множество и т.п.), то все вызовы функции без передачи этого аргумента будут работать с одним и тем же объектом.
- В нашем примере
lstуказывает на один и тот же список при первом и втором вызове. Послеextend_list(1)внутри этого единого списка появляется1. При втором вызовеextend_list(2)функция добавляет2в тот же список, поэтому результат[1, 2].
Дополнительная демонстрация того, что это один и тот же объект:

Вы увидите одинаковые id для обоих вызовов.
Разбор возможных вариантов (почему другие варианты неверны)
- "[1]\n[2]": Такой вывод бы получился, если бы при каждом вызове создавался новый список по умолчанию. Но это не соответствует правилам Python — значение по умолчанию создаётся один раз.
- "[1]\n[2, 1]": Порядок элементов показывает, что при втором вызове элемент добавился в начало или произошла перестановка; в реальном коде используется append (вставка в конец), так что порядок будет [1, 2].
- "Ошибка из-за повторного использования аргумента по умолчанию": Повторное использование изменяемого аргумента не вызывает исключение — это легальная (хотя и часто нежелательная) особенность языка.
Как избежать такой «подсказки» в будущем
Правильный и безопасный паттерн — использовать None как значение по умолчанию и создавать новый список внутри функции, если требуется:

Теперь вывод будет:

Каждый вызов без явного аргумента получает новый список.
Альтернативы:
- Всегда передавать явный пустой список при вызове:
extend_list(1, []). - Использовать иммутабельные структуры (кортежи) или возвращать новый объект вместо модификации входного.
Вывод
Избегайте использования изменяемых объектов в качестве значений по умолчанию, если вы не хотите, чтобы состояние сохранялось между вызовами. Паттерн с None — простой и надёжный способ обеспечить ожидаемое поведение функции.