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

19 Янв в 13:03
24 +1
0
Ответы
1
Проблема в том, что значение параметра по умолчанию вычисляется один раз — при определении функции — и если это изменяемый объект (например список), то все последующие вызовы будут использовать один и тот же объект.
Пример (поведение может быть неожиданным):
def foo(x=[]):
x.append(1)
return x
Вызовы:
- первый: foo() вернёт [1][1][1] - второй: foo() вернёт [1,1][1, 1][1,1] (потому что вторая функция модифицирует тот же список)
Почему так происходит (модель памяти):
- при определении функции создаётся объект по умолчанию (список) и хранится в объекте функции;
- при каждом вызове имя xxx привязывается к этому одному и тому же объекту (ссылке);
- список — изменяемый объект, поэтому операции вроде append меняют сам объект, и изменения видны при последующих вызовах.
Как исправить (стандартный приём):
def foo(x=None):
if x is None:
x = []
x.append(1)
return x
Альтернативы:
- создавать новый список при необходимости: return (x or []) + [1] (если нежелательно менять переданный список);
- использовать неизменяемые значения по умолчанию (например NoneNoneNone или кортежи), либо фабрики (например в dataclasses — field(default_factory=...)).
19 Янв в 13:44
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир