Рассмотрите фрагмент на Python: def foo(values=[]): values.append(1) return values Объясните поведение этого кода при многократных вызовах, почему возникает неожиданность и как это правильно исправить
Что происходит - По умолчанию аргументы функции вычисляются один раз — во время определения функции. В данном случае пустой список создаётся единожды и затем переиспользуется при каждом вызове. - Поэтому последовательные вызовы Первый вызов: вернёт [1][1][1]. Второй вызов: вернёт [1,1][1, 1][1,1]. Третий вызов: вернёт [1,1,1][1, 1, 1][1,1,1]. Почему неожиданно - Ожидаемое поведение часто — получать новый пустой список при каждом вызове. Но из‑за мутабельного дефолтного значения все вызовы модифицируют один и тот же объект. Правильный исправленный вариант - Использовать недефолтное значение (обычно None\texttt{None}None) и создавать новый список внутри: def foo(values=None): if values is None: values = [] values.append(1) return values Альтернативы - Можно принимать immutable дефолт (например кортеж) или явно копировать перед модификацией, но общий паттерн — дефолт None\texttt{None}None и создание объекта внутри функции.
- По умолчанию аргументы функции вычисляются один раз — во время определения функции. В данном случае пустой список создаётся единожды и затем переиспользуется при каждом вызове.
- Поэтому последовательные вызовы
Первый вызов: вернёт [1][1][1].
Второй вызов: вернёт [1,1][1, 1][1,1].
Третий вызов: вернёт [1,1,1][1, 1, 1][1,1,1].
Почему неожиданно
- Ожидаемое поведение часто — получать новый пустой список при каждом вызове. Но из‑за мутабельного дефолтного значения все вызовы модифицируют один и тот же объект.
Правильный исправленный вариант
- Использовать недефолтное значение (обычно None\texttt{None}None) и создавать новый список внутри:
def foo(values=None):
if values is None:
values = []
values.append(1)
return values
Альтернативы
- Можно принимать immutable дефолт (например кортеж) или явно копировать перед модификацией, но общий паттерн — дефолт None\texttt{None}None и создание объекта внутри функции.