Почему использовать изменяемые объекты как параметры по-умолчанию плохо?
1️⃣ Как кратко ответить
Использование изменяемых объектов как параметров по умолчанию в функциях может привести к неожиданным результатам, так как они сохраняют свое состояние между вызовами функции. Это может вызвать непредсказуемое поведение программы, если объект будет изменен.
2️⃣ Подробное объяснение темы
В Python параметры по умолчанию функции вычисляются один раз в момент определения функции, а не каждый раз при ее вызове. Это означает, что если параметр по умолчанию является изменяемым объектом, например, списком или словарем, то изменения, внесенные в этот объект, сохранятся между вызовами функции. Это может привести к неожиданным и нежелательным результатам.
Пример
Рассмотрим функцию, которая добавляет элемент в список:
def append_to_list(value, my_list=[]):
my_list.append(value)
return my_list
Что происходит в этом коде:
my_list=[]: Здесьmy_list— это параметр по умолчанию, который является изменяемым объектом (списком).my_list.append(value): Эта строка добавляетvalueв списокmy_list.return my_list: Возвращает измененный список.
Проблема
Если вызвать эту функцию несколько раз, не передавая второй аргумент, то изменения в списке будут сохраняться между вызовами:
print(append_to_list(1)) # Вывод: [1]
print(append_to_list(2)) # Вывод: [1, 2]
print(append_to_list(3)) # Вывод: [1, 2, 3]
Каждый вызов функции добавляет элемент в один и тот же список, который был создан при первом вызове функции.
Решение
Чтобы избежать этой проблемы, следует использовать None в качестве значения по умолчанию и создавать новый объект внутри функции:
def append_to_list(value, my_list=None):
if my_list is None:
my_list = []
my_list.append(value)
return my_list
Что происходит в этом коде:
my_list=None: УстанавливаемNoneв качестве значения по умолчанию.if my_list is None: my_list = []: Еслиmy_listравенNone, создаем новый список.my_list.append(value): Добавляемvalueв новый или переданный список.return my_list: Возвращаем измененный список.
Пример использования исправленной функции
print(append_to_list(1)) # Вывод: [1]
print(append_to_list(2)) # Вывод: [2]
print(append_to_list(3)) # Вывод: [3]
Теперь каждый вызов функции создает новый список, и изменения не сохраняются между вызовами.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться