Mutable default-аргументы в Python (на примере списка)

Mutable default-аргументы в Python (на примере списка)

@python_quiz

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

Код из квиза:

python

Кратко о ключевой идее

  • Значение default-параметра создаётся один раз при определении функции, а не при каждом вызове.
  • Если этот default-объект изменяемый (например, список), то все вызовы функции без явного аргумента будут работать с одним и тем же объектом и видеть его изменения.

Демонстрация поведения

python

Что получилось

  • Переменные a и b ссылаются на один и тот же список (default-список), поэтому после второго вызова оба становятся [1, 2].
  • Переменная c получает новый список, переданный явно [], и становится [3].

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

  • "a=[1], b=[1], c=[3]" — не соответствует поведению: b изменит default-список, поэтому b (и a) не останутся [1].
  • "a=[1], b=[1,2], c=[3]" — не соответствует: хотя b действительно [1,2], a после изменения тоже указывает на тот же список и станет [1,2].
  • "a=[1], b=[2], c=[3]" — не соответствует: невозможно, потому что вызов f(2) добавляет 2 к тому же списку, где уже есть 1.
  • "a=[1], b=[1,2,3], c=[3]" — не соответствует: b не станет [1,2,3] в этом примере (не было третьего без-аргументного вызова), и a тоже изменится вместе с b.

Правильный итог: a и b — один и тот же изменяемый default-список [1, 2], c — отдельный список [3].

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

python

Вывод

  • Изменяемые default-аргументы в Python сохраняют состояние между вызовами функции, что часто приводит к неожиданному поведению.
  • Предпочтительный паттерн — использовать None как маркер и создавать новый объект внутри функции, если нужен fresh default.

Report Page