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

31 Мар в 16:02
22 +1
0
Ответы
1
Коротко — потому что значение параметра по умолчанию создаётся один раз при определении функции и затем переиспользуется. В вашем коде это означает, что один и тот же изменяемый список ‘lst‘`lst`lst используется при всех вызовах, и вызов `lst.append(item)` мутирует этот общий объект.
Почему так происходит (механизм):
- Значение по умолчанию вычисляется при загрузке определения функции (в момент выполнения `def`), а не при каждом вызове.
- Если это изменяемый объект (список, словарь и т.п.), то все вызовы без явного аргумента будут работать с одной и той же ссылкой на этот объект.
- Операция `append` изменяет объект на месте, поэтому изменения видны в последующих вызовах.
Пример неожиданного поведения:
- первый вызов `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
Альтернативы/заметки:
- Если вы не хотите мутировать переданный список, можно возвращать новый: `return (lst or []) + [item]`.
- Если вы действительно хотите иметь общую память между вызовами, то текущая реализация делает это сознательно — просто документируйте такое поведение.
31 Мар в 16:08
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир