При выполнении кода на Python: def add_item(item, lst=[]): lst.append(item); return lst; — объясните, почему поведение отличается от ожиданий, покажите исправления и обсудите сценарии, где поведение с mutable default полезно

19 Мар в 12:19
19 +1
0
Ответы
1
Коротко — причина: значение параметра по умолчанию вычисляется один раз при определении функции и переиспользуется при последующих вызовах. Для изменяемого объекта (например, списка) это значит, что все вызовы без явного аргумента будут работать с одним и тем же списком.
Пример (неожиданное поведение):
```python
def add_item(item, lst=[]):
lst.append(item)
return lst
print(add_item('a')) # -> ['a']
print(add_item('b')) # -> ['a', 'b'] (ожидают ['b'])
```
Здесь список по умолчанию создан один раз при определении функции (т.е. 111 раз) и накапливает элементы при каждом новом вызове.
Как исправить (рекомендуемый способ):
```python
def add_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
print(add_item('a')) # -> ['a']
print(add_item('b')) # -> ['b']
```
Альтернативы:
- Передавать явно новый список при каждом вызове: `add_item('x', [])`.
- Использовать фабрику при создании объектов/классов (например, `field(default_factory=list)` в dataclasses).
Когда поведение с изменяемым default полезно:
- Если вы намеренно хотите хранить состояние между вызовами (аккумулятор/журнал): например, простая реализация recorder, который сохраняет все переданные значения.
- Для простого кеширования/мемоизации, когда функция должна запоминать результаты (но лучше явно документировать это или использовать структуры/декораторы для кеша).
- В редких случаях — повторное использование заранее созданного списка для экономии аллокаций, если это намеренно и контролируемо.
Совет: если функция должна вести себя «чисто» (без сохранения состояния) — используйте шаблон с `None`. Если же хранение состояния нужно — документируйте это явно, чтобы поведение не вызывало сюрпризов.
19 Мар в 14:19
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир