Рассмотрите следующий фрагмент Python: def add(x, lst=[]): lst.append(x); return lst; Объясните поведение функции при нескольких вызовах, причину и способы исправления

5 Янв в 08:38
24 +1
0
Ответы
1
Поведение
- При последовательных вызовах функции с дефолтным аргументом-списком вы будете получать нарастающий список, т.к. один и тот же объект используется во всех вызовах. Например: вызовы `add(1)`, `add(2)` дадут результаты [1][1][1], [1,2][1, 2][1,2].
Причина
- Значение дефолтного аргумента вычисляется один раз — при определении функции. Если это изменяемый объект (например, список), то все последующие вызовы используют тот же объект и видят его изменения.
Способы исправления (рекомендуемый и альтернативы)
1) Стандартный паттерн с `None`:
```python
def add(x, lst=None):
if lst is None:
lst = []
lst.append(x)
return lst
```
Пример: `add(1)` -> [1][1][1], `add(2)` -> [2][2][2] (если вызывались отдельно без передачи lst).
2) Использовать уникальный sentinel:
```python
_sentinel = object()
def add(x, lst=_sentinel):
if lst is _sentinel:
lst = []
lst.append(x)
return lst
```
3) Всегда передавать новый список явно:
```python
add(1, [])
```
4) Если вы хотите именно накапливать значения между вызовами — тогда текущее поведение корректно и его можно оставить.
Кратко: для создания нового списка при каждом вызове используйте `None` (или sentinel) как дефолт и инициализируйте список внутри функции.
5 Янв в 08:46
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир