Рассмотрите следующий Python-код: "def f(x=[]): x.append(1); return x" — почему поведение функции может быть неожиданным для новичков и какие практики языка объясняют это

16 Мар в 09:28
25 +1
0
Ответы
1
Коротко: неожиданность возникает потому, что значение аргумента по умолчанию вычисляется один раз при определении функции и сохраняется как тот же самый объект; список — изменяемый объект, поэтому каждое вызов функции меняет один и тот же список. В результате последовательные вызовы дают накопительный эффект.
Объяснение по пунктам:
- При выполнении `def f(x=[]): ...` объект `[]` создаётся один раз (при загрузке/компиляции функции), а не при каждом вызове.
- Параметр по умолчанию связывается с этим одним объектом; при мутирующих операциях (например, `append`) изменения сохраняются между вызовами.
- Это поведение вытекает из семантики Python: параметры по умолчанию — это ссылки на объекты, созданные один раз. Мутируемость (list) vs. иммутабельность (tuple, int, str) играет роль: с иммутабельными типами подобных сюрпризов обычно не бывает.
Примеры поведения:
- первый вызов `f()` вернёт [1][1][1];
- второй вызов `f()` вернёт [1,1][1,1][1,1];
- вызов `f([2])` вернёт [2,1][2,1][2,1] (если передан свой список, используется он).
Рекомендация (шаблон, избегающий проблемы):
def f(x=None):
if x is None:
x = []
x.append(1)
return x
Здесь используется «sentinel» `None`, чтобы при каждом вызове при отсутствии аргумента создавать новый список.
16 Мар в 10:53
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир