В приведённом фрагменте Python: def f(nums=[]): nums.append(1); return nums; Объясните поведение при многократных вызовах, почему это может быть ошибкой и предложите корректные варианты реализации

26 Ноя 2025 в 13:47
17 +1
0
Ответы
1
Поведение:
- В Python значение аргумента по умолчанию вычисляется один раз — при определении функции. Для `def f(nums=[])` одна и та же список-объект будет использоваться при всех вызовах, где аргумент не передан.
- Пример: первый вызов `f()` вернёт [1] [1] [1], второй `f()` — [1,1] [1,1] [1,1], третий — [1,1,1] [1,1,1] [1,1,1] и т.д. Если передать свой список, он будет изменён: `f([0])` даст [0,1] [0,1] [0,1].
Почему это может быть ошибкой:
- Неочевидное сохранение состояния между вызовами; баги трудно отлавливать.
- Побочные эффекты при повторном использовании функции и в многопоточном коде.
- Нарушает ожидание, что аргумент по умолчанию — «свежий» объект при каждом вызове.
Правильные варианты реализации:
1) Стандартный шаблон с None (рекомендуется):
def f(nums=None):
if nums is None:
nums = []
nums.append(1)
return nums
2) Невозврат мутации — каждый вызов создаёт новый список:
def f(nums=None):
if nums is None:
return [1]
return nums + [1]
3) Явное копирование входного списка (чтобы не менять переданный объект):
def f(nums=None):
nums = list(nums) if nums is not None else []
nums.append(1)
return nums
Любой из этих вариантов устраняет нежелательное хранение состояния в аргументе по умолчанию.
26 Ноя 2025 в 13:57
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир