Какое поведение ожидается, если в функции задать в качестве значения по умолчанию для аргумента пустой список?
Ответ от нейросети
sobes.tech AI
Что хотят услышать интервьюеры:
Значение по умолчанию вычисляется один раз — в момент объявления функции, а не при каждом вызове. Поэтому один и тот же пустой список будет разделяться между всеми вызовами без переданного аргумента. Это частая ошибка, и правильнее использовать None и создавать список внутри функции.
Определение:
Если в Python в параметр по умолчанию передать изменяемый объект, например [], то этот объект создаётся один раз и затем переиспользуется при каждом вызове функции. Если функция изменяет этот список, изменения сохраняются между вызовами. Это приводит к неожиданному накоплению данных.
Пример использования:
def add_item(item, items=[]):
items.append(item)
return items
print(add_item(1)) # [1]
print(add_item(2)) # [1, 2]
print(add_item(3)) # [1, 2, 3]
Без явного аргумента items каждый раз используется один и тот же список.
Пояснение кода:
- При первом определении
add_itemPython создаёт пустой список[]и привязывает его к параметруitemsкак значению по умолчанию. - Первый вызов
add_item(1)добавляет1в этот список и возвращает[1]. - Второй вызов
add_item(2)использует уже тот же самый список, поэтому в нём остаётся1, затем добавляется2. - Третий вызов продолжает работать с тем же объектом, поэтому список растёт дальше.
Правильный вариант:
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
Ключевые моменты:
- Значение по умолчанию для аргумента вычисляется один раз при определении функции.
[]как значение по умолчанию — плохая практика, если список будет изменяться внутри функции.- Изменения в таком списке сохраняются между вызовами.
- Для безопасного шаблона обычно используют
Noneи создают новый список внутри функции. - Проблема относится не только к спискам, но и к другим изменяемым объектам: словарям, множествам и т. п.