Что будет, если в значениях по умолчанию использовать изменяемые объекты?

Использование изменяемых объектов (списки, словари) в качестве значений по умолчанию в Python функциях может привести к неожиданному поведению.

Так как значение по умолчанию создается только один раз, при определении функции. Если функция изменяет этот объект, то изменения будут сохраняться между вызовами функции.

Это может привести к тому, что функция будет использовать модифицированное значение по умолчанию из предыдущего вызова, а не новое, как ожидалось.

Использование изменяемых объектов (списки, словари и т.д.) в качестве значений по умолчанию для аргументов функций в Python может привести к неожиданному и часто нежелательному поведению.

Проблема в том, что значение по умолчанию создается только один раз при определении функции. В дальнейшем, если функция вызывается без передачи значения для этого аргумента, то каждый раз будет использоваться один и тот же, ранее созданный, изменяемый объект.

Рассмотрим пример:


  def append_to_list(value, my_list=[]):
      my_list.append(value)
      return my_list

  print(append_to_list(1))  # Output: [1]
  print(append_to_list(2))  # Output: [1, 2]
  print(append_to_list(3))  # Output: [1, 2, 3]
  

В этом примере, вместо создания нового списка при каждом вызове функции, используется один и тот же список `my_list`, который изменяется при каждом вызове. Это происходит потому, что `my_list` инициализируется только один раз при определении функции.

Как правильно делать:

Чтобы избежать этой проблемы, лучше использовать `None` в качестве значения по умолчанию и создавать изменяемый объект внутри функции, если значение аргумента не было передано:


  def append_to_list(value, my_list=None):
      if my_list is None:
          my_list = []
      my_list.append(value)
      return my_list

  print(append_to_list(1))  # Output: [1]
  print(append_to_list(2))  # Output: [2]
  print(append_to_list(3))  # Output: [3]
  

В этом случае, если функция вызывается без `my_list`, то создается новый пустой список. Таким образом, при каждом вызове функции с опущенным аргументом `my_list` будет использоваться новый список.

В заключение: Избегайте использования изменяемых объектов в качестве значений по умолчанию, если не хотите, чтобы они разделялись между разными вызовами функции. Используйте `None` и создавайте изменяемые объекты внутри функции для более предсказуемого поведения.

0