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