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

10 Фев в 13:48
13 +1
0
Ответы
1
Коротко: аргумент по умолчанию вычисляется один раз — в момент определения функции — и тот же объект используется при всех последующих вызовах. Если этот объект изменяем (например список), изменения сохраняются между вызовами, поэтому поведение кажется «неожиданным».
Пример (поведение):
- при первом вызове `foo()` вернёт [1][1][1],
- при втором вызове `foo()` вернёт [1,1][1,1][1,1],
- при третьем — [1,1,1][1,1,1][1,1,1].
Почему так: при выполнении `def foo(x=[])` интерпретатор создаёт объект списка и помещает его в кортеж значений по умолчанию функции; переменная `x` при пропуске аргумента ссылается на этот уже созданный список. Поскольку список изменяется методом `append`, эти изменения видны в следующих вызовах. Времена жизни: объект по умолчанию живёт пока жив объект функции (обычно всё время работы модуля), поэтому он не «пересоздаётся» при каждом вызове.
Как избежать (правильный шаблон):
def foo(x=None):
if x is None:
x = []
x.append(111)
return x
Здесь новый список создаётся при каждом вызове, если аргумент не передан, и состояние не сохраняется между вызовами.
10 Фев в 13:54
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир