Поведение mutable-аргумента в Python

Поведение mutable-аргумента в Python

@python_quiz

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

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

Условие (код)

python

Ожидаемый вывод и объяснение

  • Первый вызов collect(1) использует список по умолчанию, который изначально пустой. В него добавляется 1 → возвращается [1].
  • Второй вызов collect(2, []) явно передаёт новый пустой список, поэтому в этот отдельный список добавляется 2 → возвращается [2].
  • Третий вызов collect(3) снова использует список по умолчанию. Этот объект тот же самый, что использовался в первом вызове и уже содержит [1]. В него добавляется 3 → возвращается [1, 3].

Итоговый вывод:

text

Анализ предложенных вариантов

  • Вариант с выводом

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

  • Вариант с выводом

[1]
[2]
[1, 3]
— совпадает с поведением функции: список по умолчанию сохраняет изменения между вызовами, а явно переданный [] создаёт независимый список.

  • Вариант с выводом

[1]
[2]
[1, 2, 3]
— предполагает, что второй вызов добавил 2 в тот же список по умолчанию, но на самом деле во втором вызове был передан отдельный список.

  • Вариант с выводом

[1]
[2]
[3, 1]
— неверен по порядку элементов: при добавлении 3 в конец списка [1] получится [1, 3], а не [3, 1].

Как избежать сюрпризов (рекомендованный паттерн)

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

Теперь каждый вызов без явного acc будет получать новый пустой список.

Дополнительные заметки

  • Поведение относится ко всем изменяемым значениям по умолчанию (списки, словари, множества и т.д.).
  • Это частая ловушка для новичков; хорошая практика — избегать изменяемых объектов как значений по умолчанию.

Вывод

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

Report Page