Дан фрагмент кода на Python: "def f(a=[]): a.append(1); return a" — объясните поведение при последовательных вызовах, укажите проблему и предложите корректное исправление
Поведение: значение дефолтного аргумента создаётся один раз при определении функции, поэтому один и тот же список переиспользуется при всех вызовах без аргумента. Пример: - первый вызов `f()` вернёт [1][1][1], - второй `f()` вернёт [1,1][1, 1][1,1], - третий `f()` вернёт [1,1,1][1, 1, 1][1,1,1]. Проблема: мутируемый объект (список) в качестве значения по умолчанию сохраняет состояние между вызовами — это невидимый побочный эффект и частая ошибка. Корректное исправление — использовать sentinel (например, `None`) и создавать новый список внутри функции: def f(a=None): if a is None: a = [] a.append(1) return a При этом последовательные вызовы `f()` будут возвращать [1][1][1], [1][1][1] и т.д. (каждый раз новый список). Альтернативы: передавать неизменяемые дефолты (кортеж) или явно копировать переданный список, если нужно сохранить исходный.
- первый вызов `f()` вернёт [1][1][1],
- второй `f()` вернёт [1,1][1, 1][1,1],
- третий `f()` вернёт [1,1,1][1, 1, 1][1,1,1].
Проблема: мутируемый объект (список) в качестве значения по умолчанию сохраняет состояние между вызовами — это невидимый побочный эффект и частая ошибка.
Корректное исправление — использовать sentinel (например, `None`) и создавать новый список внутри функции:
def f(a=None):
if a is None:
a = []
a.append(1)
return a
При этом последовательные вызовы `f()` будут возвращать [1][1][1], [1][1][1] и т.д. (каждый раз новый список). Альтернативы: передавать неизменяемые дефолты (кортеж) или явно копировать переданный список, если нужно сохранить исходный.