Найдите баг и объясните причину в следующем Python‑коде: def append_item(item, lst=[]): lst.append(item); return lst; — почему поведение иногда неожиданное, как это связано со временем создания объектов по умолчанию, и какие корректные альтернативы

7 Ноя 2025 в 07:01
16 +1
0
Ответы
1
Баг: при объявлении `def append_item(item, lst=[]): ...` дефолтный аргумент `lst` — изменяемый объект — создаётся один раз при определении функции и затем переиспользуется во всех вызовах. Из‑за этого список накапливает элементы между вызовами: например `append_item(1)` вернёт [1][1][1], затем `append_item(2)` вернёт [1,2][1,2][1,2] (а не отдельный новый список).
Причина (кратко): дефолтные значения вычисляются в момент определения функции (обычно при загрузке модуля), а не при каждом вызове. Поэтому один и тот же объект используется повторно.
Правильные альтернативы:
- Использовать `None` как маркер и создавать новый список внутри:
def append_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
- Использовать явный «фабричный» аргумент / sentinel:
_SENTINEL = object()
def append_item(item, lst=_SENTINEL):
if lst is _SENTINEL:
lst = []
lst.append(item)
return lst
- Использовать неизменяемые типы (например кортеж) если это применимо, или копировать дефолтный список перед изменением:
def append_item(item, lst=None):
lst = list(lst) if lst is not None else []
lst.append(item)
return lst
Короткий вывод: не ставьте изменяемые объекты (`[]`, `{}` и т. п.) как значения по умолчанию; вместо этого создавайте их внутри функции (обычно через `None`).
7 Ноя 2025 в 07:28
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир