Одной из распространенных «ловушек» для начинающих программистов на Python является использование изменяемых типов данных в качестве аргументов по умолчанию для функций. Давайте рассмотрим типичный пример:
def добавить_элемент(список=[]): список.append('новый элемент') return список
В этом примере функция добавить_элемент
получает один аргумент — список. Если список не передан, используется пустой список в качестве значения по умолчанию. Затем функция добавляет строку ‘новый элемент’ в список и возвращает его.
Теперь представим, что мы вызываем эту функцию несколько раз без аргументов:
print(добавить_элемент()) print(добавить_элемент()) print(добавить_элемент())
Многие ожидают увидеть три раза ‘новый элемент’, ведь каждый раз вызывается функция с пустым списком. Но вывод будет следующим:
['новый элемент'] ['новый элемент', 'новый элемент'] ['новый элемент', 'новый элемент', 'новый элемент']
Почему так происходит? Причина кроется в том, как Python обрабатывает аргументы по умолчанию. В Python значение аргумента по умолчанию определяется один раз во время определения функции. Это означает, что в нашем примере список создается один раз, когда мы определяем функцию добавить_элемент
. Затем каждый раз, когда мы вызываем функцию без аргументов, используется один и тот же список. В итоге элементы накапливаются в списке с каждым вызовом функции.
Есть простой способ обойти эту проблему — использовать None
в качестве значения по умолчанию и создавать новый список внутри функции:
def добавить_элемент(список=None): if список is None: список = [] список.append('новый элемент') return список
Теперь, если мы вызовем функцию несколько раз без аргументов, каждый раз будет создаваться новый список, и результат будет соответствовать ожиданиям:
print(добавить_элемент()) print(добавить_элемент()) print(добавить_элемент())
Вывод:
['новый элемент'] ['новый элемент'] ['новый элемент']
Таким образом, при работе с функциями в Python важно помнить о том, как обрабатываются аргументы по умолчанию, чтобы избегать «неожиданного» поведения.
Добавить комментарий